<!DOCTYPE html>
<html>

<head>
  <title>Quarkus - Writing Your Own Extension</title>
  <script id="adobe_dtm" src="https://www.redhat.com/dtm.js" type="text/javascript"></script>
  <script src="/assets/javascript/highlight.pack.js" type="text/javascript"></script>
  <META HTTP-EQUIV='Content-Security-Policy' CONTENT="default-src 'none'; script-src 'self' 'unsafe-eval' 'sha256-ANpuoVzuSex6VhqpYgsG25OHWVA1I+F6aGU04LoI+5s=' 'sha256-ipy9P/3rZZW06mTLAR0EnXvxSNcnfSDPLDuh3kzbB1w=' js.bizographics.com https://www.redhat.com assets.adobedtm.com jsonip.com https://ajax.googleapis.com https://www.googletagmanager.com https://www.google-analytics.com https://use.fontawesome.com; style-src 'self' https://fonts.googleapis.com https://use.fontawesome.com; img-src 'self' *; media-src 'self' ; frame-src https://www.googletagmanager.com https://www.youtube.com; frame-ancestors 'none'; base-uri 'none'; object-src 'none'; form-action 'none'; font-src 'self' https://use.fontawesome.com https://fonts.gstatic.com;">
  <META HTTP-EQUIV='X-Frame-Options' CONTENT="DENY">
  <META HTTP-EQUIV='X-XSS-Protection' CONTENT="1; mode=block">
  <META HTTP-EQUIV='X-Content-Type-Options' CONTENT="nosniff">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="description" content="Quarkus: Supersonic Subatomic Java">
  <meta name="twitter:card" content="summary_large_image">
  <meta name="twitter:site" content="@QuarkusIO"> 
  <meta name="twitter:creator" content="@QuarkusIO">
  <meta property="og:url" content="https://quarkus.io/guides/writing-extensions" />
  <meta property="og:title" content="Quarkus - Writing Your Own Extension" />
  <meta property="og:description" content="Quarkus: Supersonic Subatomic Java" />
  <meta property="og:image" content="/assets/images/quarkus_card.png" />
  <link rel="canonical" href="https://quarkus.io/guides/writing-extensions">
  <link rel="shortcut icon" type="image/png" href="/favicon.ico" >
  <link rel="stylesheet" href="https://quarkus.io/guides/stylesheet/config.css" />
  <link rel="stylesheet" href="/assets/css/main.css" />
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css" integrity="sha384-lKuwvrZot6UHsBSfcMvOkWwlCMgc0TaWr+30HWe3a4ltaBwTZhyTEggF5tJv8tbt" crossorigin="anonymous">
  <link rel="alternate" type="application/rss+xml"  href="https://quarkus.io/feed.xml" title="Quarkus">
  <script src="https://quarkus.io/assets/javascript/goan.js" type="text/javascript"></script>
  <script src="https://quarkus.io/assets/javascript/hl.js" type="text/javascript"></script>
</head>

<body class="guides">
  <!-- Google Tag Manager (noscript) -->
  <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-NJWS5L"
  height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
  <!-- End Google Tag Manager (noscript) -->

  <div class="nav-wrapper">
  <div class="grid-wrapper">
    <div class="width-12-12">
      <input type="checkbox" id="checkbox" />
      <nav id="main-nav" class="main-nav">
  <div class="container">
    <div class="logo-wrapper">
      
        <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_600px_reverse.png" class="project-logo" title="Quarkus"></a>
      
    </div>
    <label class="nav-toggle" for="checkbox">
      <i class="fa fa-bars"></i>
    </label>
    <div id="menu" class="menu">
      <span>
        <a href="/get-started/" class="">Get Started</a>
      </span>
      <span>
        <a href="/guides/" class="active">Guides</a>
      </span>
      <span>
        <a href="/community/" class="">Community</a>
      </span>
      <span>
        <a href="/support/" class="">Support</a>
      </span>
      <span>
        <a href="/blog/" class="">Blog</a>
      </span>
      <span>
        <a href="https://code.quarkus.io" class="button-cta secondary white">Start Coding</a>
      </span>
    </div>
  </div>
      </nav>
    </div>
  </div>
</div>

  <div class="content">
    <div class="guide">
  <div class="width-12-12">
    <h1 class="text-caps">Quarkus - Writing Your Own Extension</h1>
    <div class="hide-mobile toc"><ul class="sectlevel1">
<li><a href="#extension-philosophy">1. Extension philosophy</a>
<ul class="sectlevel2">
<li><a href="#why-an-extension-framework">1.1. Why an extension framework</a></li>
<li><a href="#favor-build-time-work-over-runtime-work">1.2. Favor build time work over runtime work</a></li>
<li><a href="#how-to-expose-configuration">1.3. How to expose configuration</a></li>
<li><a href="#expose-your-components-via-cdi">1.4. Expose your components via CDI</a></li>
<li><a href="#some-types-of-extensions">1.5. Some types of extensions</a></li>
</ul>
</li>
<li><a href="#technical-aspect">2. Technical aspect</a>
<ul class="sectlevel2">
<li><a href="#bootstrap-three-phases">2.1. Three Phases of Bootstrap and Quarkus Philosophy</a></li>
<li><a href="#maven-setup">2.2. Maven setup</a></li>
<li><a href="#build-step-processors">2.3. Build Step Processors</a></li>
<li><a href="#configuration">2.4. Configuration</a></li>
<li><a href="#conditional-step-inclusion">2.5. Conditional Step Inclusion</a></li>
<li><a href="#bytecode-recording">2.6. Bytecode Recording</a></li>
<li><a href="#contexts-and-dependency-injection">2.7. Contexts and Dependency Injection</a></li>
<li><a href="#extension-health-check">2.8. Extension Health Check</a></li>
<li><a href="#extension-metrics">2.9. Extension Metrics</a></li>
<li><a href="#customizing-json-handling-from-an-extension">2.10. Customizing JSON handling from an extension</a></li>
<li><a href="#testing-extensions">2.11. Testing Extensions</a></li>
<li><a href="#testing-hot-reload">2.12. Testing hot reload</a></li>
<li><a href="#native-executable-support">2.13. Native Executable Support</a></li>
<li><a href="#ide-support-tips">2.14. IDE support tips</a></li>
<li><a href="#troubleshooting-debugging-tips">2.15. Troubleshooting / Debugging Tips</a></li>
<li><a href="#sample-test-extension">2.16. Sample Test Extension</a></li>
</ul>
</li>
<li><a href="#configuration-reference-documentation">3. Configuration reference documentation</a>
<ul class="sectlevel2">
<li><a href="#writing-the-documentation">3.1. Writing the documentation</a></li>
<li><a href="#writing-section-documentation">3.2. Writing section documentation</a></li>
<li><a href="#generating-the-documentation">3.3. Generating the documentation</a></li>
<li><a href="#including-the-documentation-in-the-extension-guide">3.4. Including the documentation in the extension guide</a></li>
</ul>
</li>
<li><a href="#continuous-testing-of-your-extension">4. Continuous testing of your extension</a></li>
</ul></div>
    <div>
      <div id="preamble">
<div class="sectionbody">
<div class="paragraph">
<p>Quarkus extensions add a new developer focused behavior to the core offering, and consist of two distinct parts, buildtime augmentation and runtime container. The augmentation part is responsible for all metadata processing, such as reading annotations, XML descriptors etc. The output of this augmentation phase is recorded bytecode which is responsible for directly instantiating the relevant runtime services.</p>
</div>
<div class="paragraph">
<p>This means that metadata is only processed once at build time, which both saves on startup time, and also on memory
usage as the classes etc that are used for processing are not loaded (or even present) in the runtime JVM.</p>
</div>
</div>
</div>
<div class="sect1">
<h2 id="extension-philosophy"><a class="anchor" href="#extension-philosophy"></a>1. Extension philosophy</h2>
<div class="sectionbody">
<div class="paragraph">
<p>This section is a work in progress and gathers the philosophy under which extensions should be designed and written.</p>
</div>
<div class="sect2">
<h3 id="why-an-extension-framework"><a class="anchor" href="#why-an-extension-framework"></a>1.1. Why an extension framework</h3>
<div class="paragraph">
<p>Quarkus’s mission is to transform your entire application including the libraries it uses, into an artifact that uses significantly less resources than traditional approaches. These can then be used to build native applications using GraalVM.
To do this you need to analyze and understand the full "closed world" of the application.
Without the full and complete context, the best that can be achieved is partial and limited generic support.
By using the Quarkus extension approach, we can bring Java applications in line with memory footprint constrained environments like Kubernetes or cloud platforms.</p>
</div>
<div class="paragraph">
<p>The Quarkus extension framework results in significantly improved resource utilization even when GraalVM is not used (e.g. in HotSpot).
Let’s list the actions an extension performs:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Gather build time metadata and generate code</p>
<div class="ulist">
<ul>
<li>
<p>This part has nothing to do with GraalVM, it is how Quarkus starts frameworks “at build time”</p>
</li>
<li>
<p>The extension framework facilitates reading metadata, scanning classes as well as generating classes as needed</p>
</li>
<li>
<p>A small part of the extension work is executed at runtime via the generated classes, while the bulk of the work is done at build time (called deployment time)</p>
</li>
</ul>
</div>
</li>
<li>
<p>Enforce opinionated and sensible defaults based on the close world view of the application (e.g. an application with no <code>@Entity</code> does not need to start Hibernate ORM)</p>
</li>
<li>
<p>An extension hosts Substrate VM code substitution so that libraries can run on GraalVM</p>
<div class="ulist">
<ul>
<li>
<p>Most changes are pushed upstream to help the underlying library run on GraalVM</p>
</li>
<li>
<p>Not all changes can be pushed upstream, extensions host Substrate VM substitutions - which is a form of code patching - so that libraries can run</p>
</li>
</ul>
</div>
</li>
<li>
<p>Host Substrate VM code substitution to help dead code elimination based on the application needs</p>
<div class="ulist">
<ul>
<li>
<p>This is application dependant and cannot really be shared in the library itself</p>
</li>
<li>
<p>For example, Quarkus optimizes the Hibernate code because it knows it only needs a specific connection pool and cache provider</p>
</li>
</ul>
</div>
</li>
<li>
<p>Send metadata to GraalVM for example classes in need of reflection</p>
<div class="ulist">
<ul>
<li>
<p>This information is not static per library (e.g. Hibernate) but the framework has the semantic knowledge and knows which classes need to have reflection (for example @Entity classes)</p>
</li>
</ul>
</div>
</li>
</ul>
</div>
</div>
<div class="sect2">
<h3 id="favor-build-time-work-over-runtime-work"><a class="anchor" href="#favor-build-time-work-over-runtime-work"></a>1.2. Favor build time work over runtime work</h3>
<div class="paragraph">
<p>As much as possible favor doing work at build time (deployment part of the extension) as opposed to let the framework do work at startup time (runtime).
The more is done there, the smaller Quarkus applications using that extension will be and the faster they will load.</p>
</div>
</div>
<div class="sect2">
<h3 id="how-to-expose-configuration"><a class="anchor" href="#how-to-expose-configuration"></a>1.3. How to expose configuration</h3>
<div class="paragraph">
<p>Quarkus simplifies the most common usages.
This means that its defaults might be different than the library it integrates.</p>
</div>
<div class="paragraph">
<p>To make the simple experience easiest, unify the configuration in <code>application.properties</code> via MicroProfile Config.
Avoid library specific configuration files, or at least make them optional: e.g. <code>persistence.xml</code> for Hibernate ORM is optional.</p>
</div>
<div class="paragraph">
<p>Extensions should see the configuration holistically as a Quarkus application instead of focusing on the library experience.
For example <code>quarkus.database.url</code> and friends are shared between extensions as defining a database access is a shared task (instead of a <code>hibernate.</code> property for example).
The most useful configuration options should be exposed as <code>quarkus.[extension].</code> instead of the natural namespace of the library.
Less common properties can live in the library namespace.</p>
</div>
<div class="paragraph">
<p>To fully enable the close world assumptions that Quarkus can optimize best, it is better to consider configuration options as build time settled vs overridable at runtime.
Of course properties like host, port, password should be overridable at runtime.
But many properties like enable caching or setting the JDBC driver can safely require a rebuild of the application.</p>
</div>
</div>
<div class="sect2">
<h3 id="expose-your-components-via-cdi"><a class="anchor" href="#expose-your-components-via-cdi"></a>1.4. Expose your components via CDI</h3>
<div class="paragraph">
<p>Since CDI is the central programming model when it comes to component composition, frameworks and extensions should expose their components as beans that are easily consumable by user applications.
For example, Hibernate ORM exposes <code>EntityManagerFactory</code> and <code>EntityManager</code> beans, the connection pool exposes <code>DataSource</code> beans etc.
Extensions must register these bean definitions at build time.</p>
</div>
<div class="sect3">
<h4 id="beans-backed-by-classes"><a class="anchor" href="#beans-backed-by-classes"></a>1.4.1. Beans backed by classes</h4>
<div class="paragraph">
<p>An extension can produce an <a href="cdi-reference#additional_beans"><code>AdditionalBeanBuildItem</code></a> to instruct the container to read a bean definition from a class as if it was part of the original application:</p>
</div>
<div class="listingblock">
<div class="title">Bean Class Registered by <code>AdditionalBeanBuildItem</code></div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@ApplicationScoped <i class="conum" data-value="1"></i><b>(1)</b>
public class Echo {

   public String echo(String val) {
      return val;
   }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>If a bean registered by an <code>AdditionalBeanBuildItem</code> does not specify a scope then <code>@Dependent</code> is assumed.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>All other beans can inject such a bean:</p>
</div>
<div class="listingblock">
<div class="title">Bean Injecting a Bean Produced by an <code>AdditionalBeanBuildItem</code></div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Path("/hello")
public class ExampleResource {

    @Inject
    Echo echo;

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(String foo) {
        return echo.echo(foo);
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And vice versa - the extension bean can inject application beans and beans provided by other extensions:</p>
</div>
<div class="listingblock">
<div class="title">Extension Bean Injection Example</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@ApplicationScoped
public class Echo {

    @Inject
    DataSource dataSource;  <i class="conum" data-value="1"></i><b>(1)</b>

    @Inject
    Instance&lt;List&lt;String&gt;&gt; listsOfStrings; <i class="conum" data-value="2"></i><b>(2)</b>

    //...
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Inject a bean provided by other extension.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Inject all beans matching the type <code>List&lt;String&gt;</code>.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="bean_init"><a class="anchor" href="#bean_init"></a>1.4.2. Bean initialization</h4>
<div class="paragraph">
<p>Some components may require additional initialization based on information collected during augmentation.
The most straightforward solution is to obtain a bean instance and call a method directly from a build step.
However, it is <em>illegal</em> to obtain a bean instance during the augmentation phase.
The reason is that the CDI container is not started yet.
It&#8217;s started during the <a href="#bootstrap-three-phases">Static init bootstrap phase</a>.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<code>BUILD_AND_RUN_TIME_FIXED</code> and <code>RUN_TIME</code> config roots can be injected in any bean. <code>RUN_TIME</code> config roots should only be injected after the bootstrap though.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>It is possible to invoke a bean method from a <a href="#bytecode-recording">recorder method</a> though.
If you need to access a bean in a <code>@Record(STATIC_INIT)</code> build step then is must either depend on the <code>BeanContainerBuildItem</code> or wrap the logic in a <code>BeanContainerListenerBuildItem</code>.
The reason is simple - we need to make sure the CDI container is fully initialized and started.
However, it is safe to expect that the CDI container is fully initialized and running in a <code>@Record(RUNTIME_INIT)</code> build step.
You can obtain a reference to the container via <code>CDI.current()</code> or Quarkus-specific <code>Arc.container()</code>.</p>
</div>
<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
Don&#8217;t forget to make sure the bean state guarantees the visibility, e.g. via the <code>volatile</code> keyword.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
There is one significant drawback of this "late initialization" approach.
An <em>uninitialized</em> bean may be accessed by other extensions or application components that are instantiated during bootstrap.
We&#8217;ll cover a more robust solution in the <a href="#synthetic_beans">Synthetic beans</a>.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="default-beans"><a class="anchor" href="#default-beans"></a>1.4.3. Default beans</h4>
<div class="paragraph">
<p>A very useful pattern of creating such beans but also giving application code the ability to easily override some of the beans with custom implementations, is to use
the <code>@DefaultBean</code> that Quarkus provides.
This is best explained with an example.</p>
</div>
<div class="paragraph">
<p>Let us assume that the Quarkus extension needs to provide a <code>Tracer</code> bean which application code is meant to inject into its own beans.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Dependent
public class TracerConfiguration {

    @Produces
    public Tracer tracer(Reporter reporter, Configuration configuration) {
        return new Tracer(reporter, configuration);
    }

    @Produces
    @DefaultBean
    public Configuration configuration() {
        // create a Configuration
    }

    @Produces
    @DefaultBean
    public Reporter reporter(){
        // create a Reporter
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>If for example application code wants to use <code>Tracer</code>, but also needs to use a custom <code>Reporter</code> bean, such a requirement could easily be done using something like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Dependent
public class CustomTracerConfiguration {

    @Produces
    public Reporter reporter(){
        // create a custom Reporter
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="how-to-override-a-bean-defined-by-a-libraryquarkus-extension-that-doesnt-use-defaultbean"><a class="anchor" href="#how-to-override-a-bean-defined-by-a-libraryquarkus-extension-that-doesnt-use-defaultbean"></a>1.4.4. How to Override a Bean Defined by a Library/Quarkus Extension that doesn&#8217;t use @DefaultBean</h4>
<div class="paragraph">
<p>Although <code>@DefaultBean</code> is the recommended approach, it is also possible for application code to override beans provided by an extension by marking beans as a CDI <code>@Alternative</code> and including <code>@Priority</code> annotation.
Let&#8217;s show a simple example.
Suppose we work on an imaginary "quarkus-parser" extension and we have a default bean implementation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Dependent
class Parser {

  String[] parse(String expression) {
    return expression.split("::");
  }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And our extension also consumes this parser:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@ApplicationScoped
class ParserService {

  @Inject
  Parser parser;

  //...
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Now, if a user or even some other extension needs to override the default implementation of the <code>Parser</code> the simplest solution is to use CDI <code>@Alternative</code> + <code>@Priority</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Alternative <i class="conum" data-value="1"></i><b>(1)</b>
@Priority(1) <i class="conum" data-value="2"></i><b>(2)</b>
@Singleton
class MyParser extends Parser {

  String[] parse(String expression) {
    // my super impl...
  }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td><code>MyParser</code> is an alternative bean.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Enables the alternative. The priority could be any number to override the default bean but if there are multiple alternatives the highest priority wins.</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
CDI alternatives are only considered during injection and type-safe resolution. For example the default implementation would still receive observer notifications.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="synthetic_beans"><a class="anchor" href="#synthetic_beans"></a>1.4.5. Synthetic beans</h4>
<div class="paragraph">
<p>Sometimes it is very useful to be able to register a synthetic bean.
Bean attributes of a synthetic bean are not derived from a java class, method or field.
Instead, the attributes are specified by an extension.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Since the CDI container does not control the instantiation of a synthetic bean the dependency injection and other services (such as interceptors) are not supported.
In other words, it&#8217;s up to the extension to provide all required services to a synthetic bean instance.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>There are several ways to register a <a href="cdi-reference#synthetic_beans">synthetic bean</a> in Quarkus.
In this chapter, we will cover a use case that can be used to initialize extension beans in a safe manner (compared to <a href="#bean_init">Bean initialization</a>).</p>
</div>
<div class="paragraph">
<p>The <code>SyntheticBeanBuildItem</code> can be used to register a synthetic bean:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>whose instance can be easily produced through a <a href="#bytecode-recording">recorder</a>,</p>
</li>
<li>
<p>to provide a "context" bean that holds all the information collected during augmentation so that the real components do not need any "late initialization" because they can inject the context bean directly.</p>
</li>
</ul>
</div>
<div class="listingblock">
<div class="title">Instance Produced Through Recorder</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
@Record(STATIC_INIT)
SyntheticBeanBuildItem syntheticBean(TestRecorder recorder) {
   return SyntheticBeanBuildItem.configure(Foo.class).scope(Singleton.class)
                .runtimeValue(recorder.createFoo("parameters are recorder in the bytecode")) <i class="conum" data-value="1"></i><b>(1)</b>
                .done();
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The string value is recorded in the bytecode and used to initialize the instance of <code>Foo</code>.</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="title">"Context" Holder</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
@Record(STATIC_INIT)
SyntheticBeanBuildItem syntheticBean(TestRecorder recorder) {
   return SyntheticBeanBuildItem.configure(TestContext.class).scope(Singleton.class)
                .runtimeValue(recorder.createContext("parameters are recorder in the bytecode")) <i class="conum" data-value="1"></i><b>(1)</b>
                .done();
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The "real" components can inject the <code>TestContext</code> directly.</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="some-types-of-extensions"><a class="anchor" href="#some-types-of-extensions"></a>1.5. Some types of extensions</h3>
<div class="paragraph">
<p>There exist multiple stereotypes of extension, let&#8217;s list a few.</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Bare library running</dt>
<dd>
<p>This is the less sophisticated extension.
It consists of a set of patches to make sure a library runs on GraalVM.
If possible, contribute these patches upstream, not in extensions.
Second best is to write Substrate VM substitutions, which are patches applied during native image compilation.</p>
</dd>
<dt class="hdlist1">Get a framework running</dt>
<dd>
<p>A framework at runtime typically reads configuration, scan the classpath and classes for metadata (annotations, getters etc), build a metamodel on top of which it runs, find options via the service loader pattern, prepare invocation calls (reflection), proxy interfaces, etc.<br>
These operations should be done at build time and the metamodel be passed to the recorder DSL that will generate classes that will be executed at runtime and boot the framework.</p>
</dd>
<dt class="hdlist1">Get a CDI portable extension running</dt>
<dd>
<p>The CDI portable extension model is very flexible.
Too flexible to benefit from the build time boot promoted by Quarkus.
Most extension we have seen do not make use of these extreme flexibilities capabilities.
The way to port a CDI extension to Quarkus is to rewrite it as a Quarkus extension which will define the various beans at build time (deployment time in extension parlance).</p>
</dd>
</dl>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="technical-aspect"><a class="anchor" href="#technical-aspect"></a>2. Technical aspect</h2>
<div class="sectionbody">
<div class="sect2">
<h3 id="bootstrap-three-phases"><a class="anchor" href="#bootstrap-three-phases"></a>2.1. Three Phases of Bootstrap and Quarkus Philosophy</h3>
<div class="paragraph">
<p>There are three distinct bootstrap phases of a Quarkus app:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1">Augmentation</dt>
<dd>
<p>This is the first phase, and is done by the <a href="#build-step-processors">Build Step Processors</a>. These processors have access to Jandex annotation
information and can parse any descriptors and read annotations, but should not attempt to load any application classes. The output of these
build steps is some recorded bytecode, using an extension of the ObjectWeb ASM project called Gizmo(ext/gizmo), that is used to actually bootstrap the application at runtime. Depending on the <code>io.quarkus.deployment.annotations.ExecutionTime</code> value of the <code>@io.quarkus.deployment.annotations.Record</code> annotation associated with the build step,
the step may be run in a different JVM based on the following two modes.</p>
</dd>
<dt class="hdlist1">Static Init</dt>
<dd>
<p>If bytecode is recorded with <code>@Record(STATIC_INIT)</code> then it will be executed from a static init method on the main
class. For a native executable build, this code is executed in a normal JVM as part of the native build
process, and any retained objects that are produced in this stage will be directly serialized into the native executable via an image mapped file.
This means that if a framework can boot in this phase then it will have its booted state directly written to the
image, and so the boot code does not need to be executed when the image is started.</p>
<div class="paragraph">
<p>There are some restrictions on what can be done in this stage as the Substrate VM disallows some objects in the native executable. For example you should not attempt to listen on a port or start threads in this phase. In addition, it is disallowed to read run time configuration during static initialization.</p>
</div>
<div class="paragraph">
<p>In non-native pure JVM mode, there is no real difference between Static and Runtime Init, except that Static Init is always executed first. This mode benefits from the same build phase augmentation as native mode as the descriptor parsing and annotation scanning are done
at build time and any associated class/framework dependencies can be removed from the build output jar. In servers like
WildFly, deployment related classes such as XML parsers hang around for the life of the application, using up valuable
memory. Quarkus aims to eliminate this, so that the only classes loaded at runtime are actually used at runtime.</p>
</div>
<div class="paragraph">
<p>As an example, the only reason that a Quarkus application should load an XML parser is if the user is using XML in their
application. Any XML parsing of configuration should be done in the Augmentation phase.</p>
</div>
</dd>
<dt class="hdlist1">Runtime Init</dt>
<dd>
<p>If bytecode is recorded with <code>@Record(RUNTIME_INIT)</code> then it is executed from the application&#8217;s main method. This code
will be run on native executable boot. In general as little code as possible should be executed in this phase, and should
be restricted to code that needs to open ports etc.</p>
</dd>
</dl>
</div>
<div class="paragraph">
<p>Pushing as much as possible into the <code>@Record(STATIC_INIT)</code> phase allows for two different optimizations:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>In both native executable and pure JVM mode this allows the app to start as fast as possible since processing was done during build time. This also minimizes the classes/native code needed in the application to pure runtime related behaviors.</p>
</li>
<li>
<p>Another benefit with native executable mode is that Substrate can more easily eliminate features that are not used. If features are directly initialized via bytecode, Substrate can detect that a method is never called and eliminate
that method. If config is read at runtime, Substrate cannot reason about the contents of the config and so needs to keep all features in case they are required.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="maven-setup"><a class="anchor" href="#maven-setup"></a>2.2. Maven setup</h3>
<div class="paragraph">
<p>Your extension project should be setup as a multi-module project with two submodules:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>A deployment time submodule that handles the build time processing and bytecode recording.</p>
</li>
<li>
<p>A runtime submodule that contains the runtime behavior that will provide the extension behavior in the native executable or runtime JVM.</p>
</li>
</ol>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
You may want to use the <code>create-extension</code> mojo of <code>io.quarkus:quarkus-maven-plugin</code> to create these Maven modules - see the next section.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Your runtime artifact should depend on <code>io.quarkus:quarkus-core</code>, and possibly the runtime artifacts of other Quarkus
modules if you want to use functionality provided by them.
You will also need to include the <code>io.quarkus:quarkus-bootstrap-maven-plugin</code> to generate the Quarkus extension descriptor included into the runtime artifact, if you are using the Quarkus parent pom it will automatically inherit the correct configuration.
Futhermore, you&#8217;ll need to configure the <code>maven-compiler-plugin</code> to detect the <code>quarkus-extension-processor</code> annotation processor.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
By convention the deployment time artifact has the <code>-deployment</code> suffix, and the runtime artifact
has no suffix (and is what the end user adds to their project).
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="xml" class="language-xml hljs">&lt;dependencies&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
      &lt;artifactId&gt;quarkus-core&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
            &lt;artifactId&gt;quarkus-bootstrap-maven-plugin&lt;/artifactId&gt;
            &lt;!-- Executions configuration can be inherited from quarkus-build-parent --&gt;
            &lt;executions&gt;
                &lt;execution&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;extension-descriptor&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;configuration&gt;
                         &lt;deployment&gt;${project.groupId}:${project.artifactId}-deployment:${project.version}&lt;/deployment&gt;
                   &lt;/configuration&gt;
               &lt;/execution&gt;
           &lt;/executions&gt;
        &lt;/plugin&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
            &lt;configuration&gt;
                &lt;annotationProcessorPaths&gt;
                    &lt;path&gt;
                        &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                        &lt;artifactId&gt;quarkus-extension-processor&lt;/artifactId&gt;
                    &lt;/path&gt;
                &lt;/annotationProcessorPaths&gt;
            &lt;/configuration&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The above <code>maven-compiler-plugin</code> configuration requires version 3.5+.
</td>
</tr>
</table>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Under no circumstances can the runtime module depend on a deployment artifact. This would result
in pulling all the deployment time code into runtime scope, which defeats the purpose of having the split.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Your deployment time module should depend on <code>io.quarkus:quarkus-core-deployment</code>, your runtime artifact,
and possibly the deployment artifacts of other Quarkus modules if you want to use functionality provided by them.
You will also need to configure the <code>maven-compiler-plugin</code> to detect the <code>quarkus-extension-processor</code> annotation processor.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="xml" class="language-xml hljs">&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
        &lt;artifactId&gt;quarkus-core-deployment&lt;/artifactId&gt;
    &lt;/dependency&gt;
&lt;/dependencies&gt;

&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
            &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
            &lt;configuration&gt;
                &lt;annotationProcessorPaths&gt;
                    &lt;path&gt;
                        &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
                        &lt;artifactId&gt;quarkus-extension-processor&lt;/artifactId&gt;
                    &lt;/path&gt;
                &lt;/annotationProcessorPaths&gt;
            &lt;/configuration&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;</code></pre>
</div>
</div>
<div class="sect3">
<h4 id="create-new-extension-modules-using-maven"><a class="anchor" href="#create-new-extension-modules-using-maven"></a>2.2.1. Create new extension modules using Maven</h4>
<div class="paragraph">
<p>The <code>create-extension</code> mojo of <code>io.quarkus:quarkus-maven-plugin</code> can be used to generate stubs of Maven modules needed for implementing a new Quarkus extension.</p>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
This mojo can be currently used only for adding extensions to an established source tree hosting multiple extensions in one subdirectory, such as <a href="https://github.com/quarkusio/quarkus">Quarkus</a> or <a href="https://github.com/apache/camel-quarkus">Camel Quarkus</a>. Creating extension projects from scratch is not supported yet.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>As and example, let&#8217;s add a new extension called <code>my-ext</code> to the Quarkus source tree:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">git clone https://github.com/quarkusio/quarkus.git
cd quarkus
cd extensions
mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create-extension -N \
    -Dquarkus.artifactIdBase=my-ext \
    -Dquarkus.artifactIdPrefix=quarkus- \
    -Dquarkus.nameBase="My Extension"</code></pre>
</div>
</div>
<div class="paragraph">
<p>The above sequence of commands does the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Creates four new Maven modules:</p>
<div class="ulist">
<ul>
<li>
<p><code>quarkus-my-ext-parent</code> in the <code>extensions/my-ext</code> directory</p>
</li>
<li>
<p><code>quarkus-my-ext</code> in the <code>extensions/my-ext/runtime</code> directory</p>
</li>
<li>
<p><code>quarkus-my-ext-deployment</code> in the <code>extensions/my-ext/deployment</code> directory; a basic <code>MyExtProcessor</code> class is generated in this module.</p>
</li>
<li>
<p><code>quarkus-my-ext-integration-test</code> in the <code>integration-tests/my-ext/deployment</code> directory; an empty JAX-RS Resource class and two test classes (for JVM mode and native mode) are generated in this module.</p>
</li>
</ul>
</div>
</li>
<li>
<p>Links these three modules where necessary:</p>
<div class="ulist">
<ul>
<li>
<p><code>quarkus-my-ext-parent</code> is added to the <code>&lt;modules&gt;</code> of <code>quarkus-extensions-parent</code></p>
</li>
<li>
<p><code>quarkus-my-ext</code> is added to the <code>&lt;dependencyManagement&gt;</code> of the runtime BOM (Bill of Materials) <code>bom/runtime/pom.xml</code></p>
</li>
<li>
<p><code>quarkus-my-ext-deployment</code> is added to the <code>&lt;dependencyManagement&gt;</code> of the deployment BOM (Bill of Materials) <code>bom/deployment/pom.xml</code></p>
</li>
<li>
<p><code>quarkus-my-ext-integration-test</code> is added to the <code>&lt;modules&gt;</code> of <code>quarkus-integration-tests-parent</code></p>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>A Maven build performed immediately after generating the modules should fail due to a <code>fail()</code> assertion in one of the test classes.</p>
</div>
<div class="paragraph">
<p>There is one step (specific to the Quarkus source tree) that you should do manually when creating a new extension:
create a <code>quarkus-extension.yaml</code> file that describe your extension inside the runtime module <code>src/main/resources/META-INF</code> folder.</p>
</div>
<div class="paragraph">
<p>This is the <code>quarkus-extension.yaml</code> of the <code>quarkus-agroal</code> extension, you can use it as an example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="yaml" class="language-yaml hljs">name: "Agroal - Database connection pool"
metadata:
  keywords:
  - "agroal"
  - "database-connection-pool"
  - "datasource"
  - "jdbc"
  guide: "https://quarkus.io/guides/datasource"
  categories:
  - "data"
  status: "stable"</code></pre>
</div>
</div>
<div class="paragraph">
<p>Note that the parameters of the mojo that will be constant for all the extensions added to this source tree are configured in <code>extensions/pom.xml</code> so that they do not need to be passed on the command line each time a new extension is added:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="xml" class="language-xml hljs">&lt;plugin&gt;
    &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
    &lt;artifactId&gt;quarkus-maven-plugin&lt;/artifactId&gt;
    &lt;version&gt;${quarkus.version}&lt;/version&gt;
    &lt;inherited&gt;false&lt;/inherited&gt;
    &lt;!-- Settings for stubbing new extensions via
           ./mvnw quarkus:create-extension -N -Dquarkus.artifactIdBase=my-ext -Dquarkus.nameBase="My Extension"
    --&gt;
    &lt;configuration&gt;
        &lt;namePrefix xml:space="preserve"&gt;Quarkus - &lt;/namePrefix&gt;
        &lt;runtimeBomPath&gt;../bom/runtime/pom.xml&lt;/runtimeBomPath&gt;
        &lt;deploymentBomPath&gt;../bom/deployment/pom.xml&lt;/deploymentBomPath&gt;
        &lt;itestParentPath&gt;../integration-tests/pom.xml&lt;/itestParentPath&gt;
    &lt;/configuration&gt;
&lt;/plugin&gt;</code></pre>
</div>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
The <code>nameBase</code> parameter of the mojo is optional.
If you do not specify it on the command line, the plugin will derive it from <code>artifactIdBase</code> by replacing dashes with spaces and uppercasing each token.
So you may consider omitting explicit <code>nameBase</code> in some cases.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Please refer to <a href="https://github.com/quarkusio/quarkus/blob/1.7.0.Final/devtools/maven/src/main/java/io/quarkus/maven/CreateExtensionMojo.java">CreateExtensionMojo JavaDoc</a> for all the available options of the mojo.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="build-step-processors"><a class="anchor" href="#build-step-processors"></a>2.3. Build Step Processors</h3>
<div class="paragraph">
<p>Work is done at augmentation time by <em>build steps</em> which produce and consume <em>build items</em>.  The build steps found in
the deployment modules that correspond to the extensions in the project build are automatically wired together and executed
to produce the final build artifact(s).</p>
</div>
<div class="sect3">
<h4 id="build-steps"><a class="anchor" href="#build-steps"></a>2.3.1. Build steps</h4>
<div class="paragraph">
<p>A <em>build step</em> is a method which is annotated with the <code>@io.quarkus.deployment.annotations.BuildStep</code> annotation.  Each
build step may <a href="#consuming-values">consume</a> items that are produced by earlier stages, and <a href="#producing-values">produce</a> items
that can be consumed by later stages. Build steps are normally only run when they produce a build item that is
ultimately consumed by another step.</p>
</div>
<div class="paragraph">
<p>Build steps are normally placed on plain classes within an extension&#8217;s deployment module.  The classes are automatically
instantiated during the augment process and utilize <a href="#injection">injection</a>.</p>
</div>
</div>
<div class="sect3">
<h4 id="build-items"><a class="anchor" href="#build-items"></a>2.3.2. Build items</h4>
<div class="paragraph">
<p>Build items are concrete, final subclasses of the abstract <code>io.quarkus.builder.item.BuildItem</code> class.  Each build item represents
some unit of information that must be passed from one stage to another.  The base <code>BuildItem</code> class may not itself be directly
subclassed; rather, there are abstract subclasses for each of the kinds of build item subclasses that <em>may</em> be created:
<a href="#simple-build-items">simple</a>, <a href="#multi-build-items">multi</a>, and <a href="#empty-build-items">empty</a>.</p>
</div>
<div class="paragraph">
<p>Think of build items as a way for different extensions to communicate with one another.  For example, a build item can:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>expose the fact that a database configuration exists</p>
</li>
<li>
<p>consume that database configuration (e.g. a connection pool extension or an ORM extension)</p>
</li>
<li>
<p>ask an extension to do work for another extension: e.g. an extension wanting to define a new CDI bean and asking the ArC extension
to do so</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>This is a very flexible mechanism.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>BuildItem</code> instances should be immutable, as the producer/consumer model does not allow for mutation to be correctly
ordered. This is not enforced but failure to adhere to this rule can result in race conditions.
</td>
</tr>
</table>
</div>
<div class="sect4">
<h5 id="simple-build-items"><a class="anchor" href="#simple-build-items"></a>2.3.2.1. Simple build items</h5>
<div class="paragraph">
<p>Simple build items are final classes which extend <code>io.quarkus.builder.item.SimpleBuildItem</code>.  Simple build items may only
be produced by one step in a given build; if multiple steps in a build declare that they produce the same simple build item,
an error is raised.  Any number of build steps may consume a simple build item.  A build step which consumes a simple
build item will always run <em>after</em> the build step which produced that item.</p>
</div>
<div class="listingblock">
<div class="title">Example of a single build item</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/**
 * The build item which represents the Jandex index of the application,
 * and would normally be used by many build steps to find usages
 * of annotations.
 */
public final class ApplicationIndexBuildItem extends SimpleBuildItem {

    private final Index index;

    public ApplicationIndexBuildItem(Index index) {
        this.index = index;
    }

    public Index getIndex() {
        return index;
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="multi-build-items"><a class="anchor" href="#multi-build-items"></a>2.3.2.2. Multi build items</h5>
<div class="paragraph">
<p>Multiple or "multi" build items are final classes which extend <code>io.quarkus.builder.item.MultiBuildItem</code>.  Any number of
multi build items of a given class may be produced by any number of steps, but any steps which consume multi build items
will only run <em>after</em> every step which can produce them has run.</p>
</div>
<div class="listingblock">
<div class="title">Example of a multiple build item</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">public final class ServiceWriterBuildItem extends MultiBuildItem {
    private final String serviceName;
    private final List&lt;String&gt; implementations;

    public ServiceWriterBuildItem(String serviceName, String... implementations) {
        this.serviceName = serviceName;
        // Make sure it's immutable
        this.implementations = Collections.unmodifiableList(
            Arrays.asList(
                implementations.clone()
            )
        );
    }

    public String getServiceName() {
        return serviceName;
    }

    public List&lt;String&gt; getImplementations() {
        return implementations;
    }
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Example of multiple build item usage</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/**
 * This build step produces a single multi build item that declares two
 * providers of one configuration-related service.
 */
@BuildStep
public ServiceWriterBuildItem registerOneService() {
    return new ServiceWriterBuildItem(
        Converter.class.getName(),
        MyFirstConfigConverterImpl.class.getName(),
        MySecondConfigConverterImpl.class.getName()
    );
}

/**
 * This build step produces several multi build items that declare multiple
 * providers of multiple configuration-related services.
 */
@BuildStep
public void registerSeveralServices(
    BuildProducer&lt;ServiceWriterBuildItem&gt; providerProducer
) {
    providerProducer.produce(new ServiceWriterBuildItem(
        Converter.class.getName(),
        MyThirdConfigConverterImpl.class.getName(),
        MyFourthConfigConverterImpl.class.getName()
    ));
    providerProducer.produce(new ServiceWriterBuildItem(
        ConfigSource.class.getName(),
        MyConfigSourceImpl.class.getName()
    ));
}

/**
 * This build step aggregates all the produced service providers
 * and outputs them as resources.
 */
@BuildStep
public void produceServiceFiles(
    List&lt;ServiceWriterBuildItem&gt; items,
    BuildProducer&lt;GeneratedResourceBuildItem&gt; resourceProducer
) throws IOException {
    // Aggregate all of the providers

    Map&lt;String, Set&lt;String&gt;&gt; map = new HashMap&lt;&gt;();
    for (ServiceWriterBuildItem item : items) {
        String serviceName = item.getName();
        for (String implName : item.getImplementations()) {
            map.computeIfAbsent(
                serviceName,
                (k, v) -&gt; new LinkedHashSet&lt;&gt;()
            ).add(implName);
        }
    }

    // Now produce the resource(s) for the SPI files
    for (Map.Entry&lt;String, Set&lt;String&gt;&gt; entry : map.entrySet()) {
        String serviceName = entry.getKey();
        try (ByteArrayOutputStream os = new ByteArrayOutputStream()) {
            try (OutputStreamWriter w = new OutputStreamWriter(os, StandardCharsets.UTF_8)) {
                for (String implName : entry.getValue()) {
                    w.write(implName);
                    w.write(System.lineSeparator());
                }
            }
            w.flush();
            resourceProducer.produce(
                new GeneratedResourceBuildItem(
                    "META-INF/services/" + serviceName,
                    os.toByteArray()
                )
            );
        }
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="empty-build-items"><a class="anchor" href="#empty-build-items"></a>2.3.2.3. Empty build items</h5>
<div class="paragraph">
<p>Empty build items are final (usually empty) classes which extend <code>io.quarkus.builder.item.EmptyBuildItem</code>.
They represent build items that don&#8217;t actually carry any data, and allow such items to be produced and consumed
without having to instantiate empty classes.  They cannot themselves be instantiated.</p>
</div>
<div class="listingblock">
<div class="title">Example of an empty build item</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">public final class NativeImageBuildItem extends EmptyBuildItem {
    // empty
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Empty build items can represent "barriers" which can impose ordering between steps.  They can also be used in
the same way that popular build systems use "pseudo-targets", which is to say that the build item can represent a
conceptual goal that does not have a concrete representation.</p>
</div>
<div class="listingblock">
<div class="title">Example of usage of an empty build item in a "pseudo-target" style</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/**
 * Contrived build step that produces the native image on disk.  The main augmentation
 * step (which is run by Maven or Gradle) would be declared to consume this empty item,
 * causing this step to be run.
 */
@BuildStep
@Produce(NativeImageBuildItem.class)
void produceNativeImage() {
    // ...
    // (produce the native image)
    // ...
}</code></pre>
</div>
</div>
<div class="listingblock">
<div class="title">Example of usage of an empty build item in a "barrier" style</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/**
 * This would always run after {@link #produceNativeImage()} completes, producing
 * an instance of {@code SomeOtherBuildItem}.
 */
@BuildStep
@Consume(NativeImageBuildItem.class)
SomeOtherBuildItem secondBuildStep() {
    return new SomeOtherBuildItem("foobar");
}</code></pre>
</div>
</div>
</div>
</div>
<div class="sect3">
<h4 id="injection"><a class="anchor" href="#injection"></a>2.3.3. Injection</h4>
<div class="paragraph">
<p>Classes which contain build steps support the following types of injection:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Constructor parameter injection</p>
</li>
<li>
<p>Field injection</p>
</li>
<li>
<p>Method parameter injection (for build step methods only)</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Build step classes are instantiated and injected for each build step invocation, and are discarded afterwards.  State
should only be communicated between build steps by way of build items, even if the steps are on the same class.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Final fields are not considered for injection, but can be populated by way of constructor parameter injection
if desired.  Static fields are never considered for injection.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The types of values that can be injected include:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><a href="#build-items">Build items</a> produced by previous build steps</p>
</li>
<li>
<p><a href="#producing-values">Build producers</a> to produce items for subsequent build steps</p>
</li>
<li>
<p><a href="#configuration-roots">Configuration root</a> types</p>
</li>
<li>
<p>Template objects for <a href="#bytecode-recording">bytecode recording</a></p>
</li>
</ul>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
Objects which are injected into a build step method or its class <em>must not</em> be used outside of that method&#8217;s
execution.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Injection is resolved at compile time via an annotation processor,
and the resulting code does not have permission to inject private fields or invoke private methods.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="producing-values"><a class="anchor" href="#producing-values"></a>2.3.4. Producing values</h4>
<div class="paragraph">
<p>A build step may produce values for subsequent steps in several possible ways:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>By returning a <a href="#simple-build-items">simple build item</a> or <a href="#multi-build-items">multi build item</a> instance</p>
</li>
<li>
<p>By returning a <code>List</code> of a multi build item class</p>
</li>
<li>
<p>By injecting a <code>BuildProducer</code> of a simple or multi build item class</p>
</li>
<li>
<p>By annotating the method with <code>@io.quarkus.deployment.annotations.Produce</code>, giving the class name of a
<a href="#empty-build-items">empty build item</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>If a simple build item is declared on a build step, it <em>must</em> be produced during that build step, otherwise an error
will result.  Build producers which are injected into steps <em>must not</em> be used outside of that step.</p>
</div>
<div class="paragraph">
<p>Note that a <code>@BuildStep</code> method will only be called if it produces something that another consumer or the final output
requires. If there is no consumer for a particular item then it will not be produced. What is required will depend on
the final target that is being produced.  For example, when running in developer mode the final output will not ask
for GraalVM-specific build items such as <code>ReflectiveClassBuildItem</code>, so methods that only produce these
items will not be invoked.</p>
</div>
</div>
<div class="sect3">
<h4 id="consuming-values"><a class="anchor" href="#consuming-values"></a>2.3.5. Consuming values</h4>
<div class="paragraph">
<p>A build step may consume values from previous steps in the following ways:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>By injecting a <a href="#simple-build-items">simple build item</a></p>
</li>
<li>
<p>By injecting an <code>Optional</code> of a simple build item class</p>
</li>
<li>
<p>By injecting a <code>List</code> of a <a href="#multi-build-items">multi build item</a> class</p>
</li>
<li>
<p>By annotating the method with <code>@io.quarkus.deployment.annotations.Consume</code>, giving the class name of a
<a href="#empty-build-items">empty build item</a></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Normally it is an error for a step which is included to consume a simple build item that is not produced by any other
step.  In this way, it is guaranteed that all of the declared values will be present and non-<code>null</code> when a step is run.</p>
</div>
<div class="paragraph">
<p>Sometimes a value isn&#8217;t necessary for the build to complete, but might inform some behavior of the build step if it is
present.  In this case, the value can be optionally injected.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Multi build values are always considered <em>optional</em>.  If not present, an empty list will be injected.
</td>
</tr>
</table>
</div>
<div class="sect4">
<h5 id="producing-weak-values"><a class="anchor" href="#producing-weak-values"></a>2.3.5.1. Weak value production</h5>
<div class="paragraph">
<p>Normally a build step is included whenever it produces any build item which is in turn consumed by any other build step.  In this way,
only the steps necessary to produce the final artifact(s) are included, and steps which pertain to extensions which are
not installed or which only produce build items which are not relevant for the given artifact type are excluded.</p>
</div>
<div class="paragraph">
<p>For cases where this is not desired behavior, the <code>@io.quarkus.deployment.annotations.Weak</code> annotation may be used.  This
annotation indicates that the build step should not automatically be included solely on the basis of producing the annotated value.</p>
</div>
<div class="listingblock">
<div class="title">Example of producing a build item weakly</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/**
 * This build step is only run if something consumes the ExecutorClassBuildItem.
 */
@BuildStep
void createExecutor(
        @Weak BuildProducer&lt;GeneratedClassBuildItem&gt; classConsumer,
        BuildProducer&lt;ExecutorClassBuildItem&gt; executorClassConsumer
) {
        ClassWriter cw = new ClassWriter(Gizmo.ASM_API_VERSION);
        String className = generateClassThatCreatesExecutor(cw); <i class="conum" data-value="1"></i><b>(1)</b>
        classConsumer.produce(new GeneratedClassBuildItem(true, className, cw.toByteArray()));
        executorClassConsumer.produce(new ExecutorClassBuildItem(className));
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This method (not provided in this example) would generate the class using the ASM API.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Certain types of build items are generally always consumed, such as generated classes or resources.
An extension might produce a build item along with a generated class to facilitate the usage
of that build item.  Such a build step would use the <code>@Weak</code> annotation on the generated class build item, while normally
producing the other build item.  If the other build item is ultimately consumed by something, then the step would run
and the class would be generated.  If nothing consumes the other build item, the step would not be included in the build
process.</p>
</div>
<div class="paragraph">
<p>In the example above, <code>GeneratedClassBuildItem</code> would only be produced if <code>ExecutorClassBuildItem</code> is consumed by
some other build step.</p>
</div>
<div class="paragraph">
<p>Note that when using <a href="#bytecode-recording">bytecode recording</a>, the implicitly generated class can be declared to be weak by
using the <code>optional</code> attribute of the <code>@io.quarkus.deployment.annotations.Record</code> annotation.</p>
</div>
<div class="listingblock">
<div class="title">Example of using a bytecode recorder where the generated class is weakly produced</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/**
 * This build step is only run if something consumes the ExecutorBuildItem.
 */
@BuildStep
@Record(value = ExecutionTime.RUNTIME_INIT, optional = true) <i class="conum" data-value="1"></i><b>(1)</b>
ExecutorBuildItem createExecutor( <i class="conum" data-value="2"></i><b>(2)</b>
        ExecutorTemplate executorTemplate,
        ThreadPoolConfig threadPoolConfig
) {

    return new ExecutorBuildItem(
        setupTemplate.setupRunTime(
            shutdownContextBuildItem,
            threadPoolConfig,
            launchModeBuildItem.getLaunchMode()
        )
    );
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Note the <code>optional</code> attribute.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This example is using recorder proxies; see the section on <a href="#bytecode-recording">bytecode recording</a> for more information.</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect3">
<h4 id="capabilities"><a class="anchor" href="#capabilities"></a>2.3.6. Capabilities</h4>
<div class="paragraph">
<p>The <code>@BuildStep</code> annotation has a <code>providesCapabilities</code> property that can be used to provide capability information
to other extensions about what is present in the current application. Capabilities are simply strings that are used to
describe an extension. Capabilities should generally be named after an extensions root package, for example the transactions
extension will provide <code>io.quarkus.transactions</code>.</p>
</div>
<div class="paragraph">
<p>To check if a capability is present you can inject the <code>io.quarkus.deployment.Capabilities</code> object and call
<code>isCapabilityPresent</code>.</p>
</div>
<div class="paragraph">
<p>Capabilities should be used when checking for the presence of an extension rather than class path based checks.</p>
</div>
</div>
<div class="sect3">
<h4 id="application-archives"><a class="anchor" href="#application-archives"></a>2.3.7. Application Archives</h4>
<div class="paragraph">
<p>The <code>@BuildStep</code> annotation can also register marker files that determine which archives on the class path are considered
to be 'Application Archives', and will therefore get indexed. This is done via the <code>applicationArchiveMarkers</code>. For
example the ArC extension registers <code>META-INF/beans.xml</code>, which means that all archives on the class path with a <code>beans.xml</code>
file will be indexed.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<code>BuildStep.applicationArchiveMarkers()</code> is deprecated and will be removed at some point post Quarkus 1.1. Extensions are encouraged to use <code>io.quarkus.deployment.builditem.AdditionalApplicationArchiveMarkerBuildItem</code> instead.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="using-threads-context-class-loader"><a class="anchor" href="#using-threads-context-class-loader"></a>2.3.8. Using Thread&#8217;s Context Class Loader</h4>
<div class="paragraph">
<p>The build step will be run with a TCCL that can load user classes from the deployment in a transformer-safe way.
This class loader only lasts for the life of the augmentation, and is discarded afterwards.
The classes will be loaded again in a different class loader at runtime.
This means that loading a class during augmentation does not stop it from being transformed when running in the development/test mode.</p>
</div>
</div>
<div class="sect3">
<h4 id="adding-external-jars-to-the-indexer-with-indexdependencybuilditem"><a class="anchor" href="#adding-external-jars-to-the-indexer-with-indexdependencybuilditem"></a>2.3.9. Adding external JARs to the indexer with IndexDependencyBuildItem</h4>
<div class="paragraph">
<p>The index of scanned classes will not automatically include your external class dependencies.
To add dependencies, create a <code>@BuildStep</code> that produces <code>IndexDependencyBuildItem</code> objects, for a <code>groupId</code> and <code>artifactId</code>.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
It is important to specify all the required artifacts to be added to the indexer. No artifacts are implicitly added transitively.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The <code>Amazon Alexa</code> extension adds dependent libraries from the Alexa SDK that are used in Jackson JSON transformations, in order for the reflective classes to identified and included at <code>BUILD_TIME</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">   @BuildStep
    void addDependencies(BuildProducer&lt;IndexDependencyBuildItem&gt; indexDependency) {
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-runtime"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-model"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-lambda-support"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-servlet-support"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-dynamodb-persistence-adapter"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-apache-client"));
        indexDependency.produce(new IndexDependencyBuildItem("com.amazon.alexa", "ask-sdk-model-runtime"));
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>With the artifacts added to the <code>Jandex</code> indexer, you can now search the index to identify classes implementing an interface, sub-classes of a specific class, or classes with a target annotation.</p>
</div>
<div class="paragraph">
<p>For example, the <code>Jackson</code> extension uses code like below to search for annotations used in JSON deserialization,
and add them to the reflective hierarchy for <code>BUILD_TIME</code> analysis.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">    DotName JSON_DESERIALIZE = DotName.createSimple(JsonDeserialize.class.getName());

    IndexView index = combinedIndexBuildItem.getIndex();

    // handle the various @JsonDeserialize cases
    for (AnnotationInstance deserializeInstance : index.getAnnotations(JSON_DESERIALIZE)) {
        AnnotationTarget annotationTarget = deserializeInstance.target();
        if (CLASS.equals(annotationTarget.kind())) {
            DotName dotName = annotationTarget.asClass().name();
            Type jandexType = Type.create(dotName, Type.Kind.CLASS);
            reflectiveHierarchyClass.produce(new ReflectiveHierarchyBuildItem(jandexType));
        }

    }</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="configuration"><a class="anchor" href="#configuration"></a>2.4. Configuration</h3>
<div class="paragraph">
<p>Configuration in Quarkus is based on SmallRye Config, an implementation of the MicroProfile Config specification.
All of the standard features of MP-Config are supported; in addition, there are several extensions which are made available
by the SmallRye Config project as well as by Quarkus itself.</p>
</div>
<div class="paragraph">
<p>The value of these properties is configured in a <code>application.properties</code> file that follows the MicroProfile config format.</p>
</div>
<div class="paragraph">
<p>Configuration of Quarkus extensions is injection-based, using annotations.</p>
</div>
<div class="sect3">
<h4 id="configuration-keys"><a class="anchor" href="#configuration-keys"></a>2.4.1. Configuration Keys</h4>
<div class="paragraph">
<p>Leaf configuration keys are mapped to non-<code>private</code> fields via the <code>@io.quarkus.runtime.annotations.ConfigItem</code> annotation.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Though the SmallRye Config project is used for implementation, the standard <code>@ConfigProperty</code> annotation does not have the
same semantics that are needed to support configuration within extensions.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Configuration keys are normally derived from the field names that they are tied to.  This is done by de-camel-casing the name and then
joining the segments with hyphens (<code>-</code>).  Some examples:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>bindAddress</code> becomes <code>bind-address</code></p>
</li>
<li>
<p><code>keepAliveTime</code> becomes <code>keep-alive-time</code></p>
</li>
<li>
<p><code>requestDNSTimeout</code> becomes <code>request-dns-timeout</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The name can also be explicitly specified by giving a <code>name</code> attribute to the <code>@ConfigItem</code> annotation.</p>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
Though it is possible to override the configuration key name using the <code>name</code> attribute of <code>@ConfigItem</code>,
normally this should only be done in cases where (for example) the configuration key name is the same as a Java keyword.
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="configuration-value-types"><a class="anchor" href="#configuration-value-types"></a>2.4.2. Configuration Value types</h4>
<div class="paragraph">
<p>The type of the field with the <code>@ConfigItem</code> annotation determines the conversion that is applied to it.  Quarkus
extensions may use the full range of configuration types made available by SmallRye Config, which includes:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>All primitive types and primitive wrapper types</p>
</li>
<li>
<p><code>String</code></p>
</li>
<li>
<p>Any type which has a constructor accepting a single argument of type <code>String</code> or <code>CharSequence</code></p>
</li>
<li>
<p>Any type which has a static method named <code>of</code> which accepts a single argument of type <code>String</code></p>
</li>
<li>
<p>Any type which has a static method named <code>valueOf</code> or <code>parse</code> which accepts a single argument of type <code>CharSequence</code> or <code>String</code></p>
</li>
<li>
<p><code>java.time.Duration</code></p>
</li>
<li>
<p><code>java.util.regex.Pattern</code></p>
</li>
<li>
<p><code>java.nio.file.Path</code></p>
</li>
<li>
<p><code>io.quarkus.runtime.configuration.MemorySize</code> to represent data sizes</p>
</li>
<li>
<p><code>java.net.InetSocketAddress</code>, <code>java.net.InetAddress</code> and <code>org.wildfly.common.net.CidrAddress</code></p>
</li>
<li>
<p>A <code>List</code> or <code>Optional</code> of any of the above types</p>
</li>
<li>
<p><code>OptionalInt</code>, <code>OptionalLong</code>, <code>OptionalDouble</code></p>
</li>
</ul>
</div>
<div class="paragraph">
<p>In addition, custom converters may be registered by adding their fully qualified class name in file
<code>META-INF/services/org.eclipse.microprofile.config.spi.Converter</code>.</p>
</div>
<div class="paragraph">
<p>Though these implicit converters use reflection, Quarkus will automatically ensure that they are loaded at the appropriate time.</p>
</div>
<div class="sect4">
<h5 id="optional-values"><a class="anchor" href="#optional-values"></a>2.4.2.1. Optional Values</h5>
<div class="paragraph">
<p>If the configuration type is one of the optional types, then empty values are allowed for the configuration key; otherwise,
specification of an empty value will result in a configuration error which prevents the application from starting.  This
is especially relevant to configuration properties of inherently emptiable values such as <code>List</code>, <code>Set</code>, and <code>String</code>.  Such
value types will never be empty; in the event of an empty value, an empty <code>Optional</code> is always used.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuration-default-values"><a class="anchor" href="#configuration-default-values"></a>2.4.3. Configuration Default Values</h4>
<div class="paragraph">
<p>A configuration item can be marked to have a default value.  The default value is used when no matching configuration key
is specified in the configuration.</p>
</div>
<div class="paragraph">
<p>Configuration items with a primitive type (such as <code>int</code> or <code>boolean</code>) implicitly use a default value of <code>0</code> or <code>false</code>.  The
sole exception to this rule is the <code>char</code> type which does not have an implicit default value.</p>
</div>
<div class="paragraph">
<p>A property with a default value is not implicitly optional.  If a non-optional configuration item with a default value
is explicitly specified to have an empty value, the application will report a configuration error and will not start.  If
it is desired for a property to have a default value and also be optional, it must have an <code>Optional</code> type as described above.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuration-groups"><a class="anchor" href="#configuration-groups"></a>2.4.4. Configuration Groups</h4>
<div class="paragraph">
<p>Configuration values are always collected into grouping classes which are marked with the <code>@io.quarkus.runtime.annotations.ConfigGroup</code>
annotation.  These classes contain a field for each key within its group.  In addition, configuration groups can be nested.</p>
</div>
<div class="sect4">
<h5 id="optional-configuration-groups"><a class="anchor" href="#optional-configuration-groups"></a>2.4.4.1. Optional Configuration Groups</h5>
<div class="paragraph">
<p>A nested configuration group may be wrapped with an <code>Optional</code> type.  In this case, the group is not populated unless one
or more properties within that group are specified in the configuration.  If the group is populated, then any required
properties in the group must also be specified otherwise a configuration error will be reported and the application will
not start.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuration-maps"><a class="anchor" href="#configuration-maps"></a>2.4.5. Configuration Maps</h4>
<div class="paragraph">
<p>A <code>Map</code> can be used for configuration at any position where a configuration group would be allowed.  The key type of such a
map <strong>must</strong> be <code>String</code>, and its value may be either a configuration group class or a valid leaf type.  The configuration
key segment following the map&#8217;s key segment will be used as the key for map values.</p>
</div>
</div>
<div class="sect3">
<h4 id="configuration-roots"><a class="anchor" href="#configuration-roots"></a>2.4.6. Configuration Roots</h4>
<div class="paragraph">
<p>Configuration roots are configuration groups that appear in the root of the configuration tree.  A configuration property&#8217;s full
name is determined by joining the string <code>quarkus.</code> with the hyphenated name of the fields that form the path from the root to the
leaf field.  For example, if I define a configuration root group called <code>ThreadPool</code>, with a nested group in a field named <code>sizing</code>
that in turn contains a field called <code>minSize</code>, the final configuration property will be called <code>quarkus.thread-pool.sizing.min-size</code>.</p>
</div>
<div class="paragraph">
<p>A configuration root&#8217;s name can be given with the <code>name</code> property, or it can be inferred from the class name.  If the latter,
then the configuration key will be the class name, minus any <code>Config</code> or <code>Configuration</code> suffix, broken up by camel-case,
lowercased, and re-joined using hyphens (<code>-</code>).</p>
</div>
<div class="paragraph">
<p>A configuration root&#8217;s class name can contain an extra suffix segment for the case where there are configuration
roots for multiple <a href="#configuration-root-phases">Configuration Root Phases</a>.  Classes which correspond to the <code>BUILD_TIME</code> and <code>BUILD_AND_RUN_TIME_FIXED</code>
may end with <code>BuildTimeConfig</code> or <code>BuildTimeConfiguration</code>, and classes which correspond to the <code>RUN_TIME</code> phase
may end with <code>RuntimeConfig</code>, <code>RunTimeConfig</code>, <code>RuntimeConfiguration</code> or <code>RunTimeConfiguration</code>.</p>
</div>
<div class="paragraph">
<p>Note: The current implementation is still using injection site to determine the root set, so to avoid migration problems, it
is recommended that the injection site (field or parameter) have the same name as the configuration root class until
this change is complete.</p>
</div>
<div class="sect4">
<h5 id="configuration-root-phases"><a class="anchor" href="#configuration-root-phases"></a>2.4.6.1. Configuration Root Phases</h5>
<div class="paragraph">
<p>Configuration roots are strictly bound by configuration phase, and attempting to access a configuration root from outside of its corresponding phase will result in an error.
A configuration root dictates when its contained keys are read from configuration, and when they are available to applications.  The phases defined by <code>io.quarkus.runtime.annotations.ConfigPhase</code> are as follows:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 20%;">
<col style="width: 6.6666%;">
<col style="width: 6.6666%;">
<col style="width: 6.6666%;">
<col style="width: 6.6666%;">
<col style="width: 53.3336%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Phase name</th>
<th class="tableblock halign-center valign-top">Read &amp; avail. at build time</th>
<th class="tableblock halign-center valign-top">Avail. at run time</th>
<th class="tableblock halign-center valign-top">Read during static init</th>
<th class="tableblock halign-center valign-top">Re-read during startup (native executable)</th>
<th class="tableblock halign-left valign-top">Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>BUILD_TIME</code></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✓</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✗</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✗</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✗</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Appropriate for things which affect build.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>BUILD_AND_RUN_TIME_FIXED</code></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✓</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✓</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✗</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✗</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Appropriate for things which affect build and must be visible for run time code.  Not read from config at run time.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code>RUN_TIME</code></p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✗</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✓</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✓</p></td>
<td class="tableblock halign-center valign-top"><p class="tableblock">✓</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Not available at build, read at start in all modes.</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>For all cases other than the <code>BUILD_TIME</code> case, the configuration root class and all of the configuration groups and types contained therein must be located in, or reachable from, the extension&#8217;s run time artifact.  Configuration roots of phase <code>BUILD_TIME</code> may be located in or reachable from either of the extension&#8217;s run time or deployment artifacts.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="configuration-example"><a class="anchor" href="#configuration-example"></a>2.4.7. Configuration Example</h4>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">import io.quarkus.runtime.annotations.ConfigItem;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.quarkus.runtime.annotations.DefaultConverter

import java.io.File;
import java.util.logging.Level;

@ConfigGroup <i class="conum" data-value="1"></i><b>(1)</b>
public class FileConfig {

    /**
     * Enable logging to a file.
     */
    @ConfigItem(defaultValue = "true")
    boolean enable;

    /**
     * The log format.
     */
    @ConfigItem(defaultValue = "%d{yyyy-MM-dd HH:mm:ss,SSS} %h %N[%i] %-5p [%c{1.}] (%t) %s%e%n")
    String format;

    /**
     * The level of logs to be written into the file.
     */
    @ConfigItem(defaultValue = "ALL")
    Level level;

    /**
     * The name of the file in which logs will be written.
     */
    @ConfigItem(defaultValue = "application.log")
    File path;

}

/**
 * Logging configuration.
 */
@ConfigRoot(phase = ConfigPhase.RUN_TIME) <i class="conum" data-value="2"></i><b>(2)</b>
public class LogConfiguration {

    // ...

    /**
     * Configuration properties for the logging file handler.
     */
    FileConfig file;
}

public class LoggingProcessor {
    // ...

    /**
     * Logging configuration.
     */
    <i class="conum" data-value="3"></i><b>(3)</b>
    LogConfiguration config;
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A configuration property name can be split into segments. For example, a property name like
<code>quarkus.log.file.enable</code> can be split into the following segments:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>quarkus</code> - a namespace claimed by Quarkus which is a prefix for all <code>@ConfigRoot</code> classes,</p>
</li>
<li>
<p><code>log</code> - a name segment which corresponds to the <code>LogConfiguration</code> class annotated with <code>@ConfigRoot</code>,</p>
</li>
<li>
<p><code>file</code> - a name segment which corresponds to the <code>file</code> field in this class,</p>
</li>
<li>
<p><code>enabled</code> - a name segment which corresponds to <code>enable</code> field in <code>FileConfig</code> class annotated with <code>@ConfigGroup</code>.</p>
</li>
</ul>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The <code>FileConfig</code> class is annotated with <code>@ConfigGroup</code> to indicate that this is an aggregate
configuration object containing a collection of configurable properties, rather than being a simple configuration
key type.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The <code>@ConfigRoot</code> annotation indicates that this object is a configuration root group, in this case one which
corresponds to a <code>log</code> segment. A class name is used to link configuration root group with the segment from a
property name. The <code>Configuration</code> part is stripped off from a <code>LogConfiguration</code> class name and the remaining <code>Log</code>
is lowercased to become a <code>log</code>. Since all <code>@ConfigRoot</code> annotated classes uses <code>quarkus</code> as a prefix, this finally
becomes <code>quarkus.log</code> and represents the properties which names begin with <code>quarkus.log.*</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Here the <code>LoggingProcessor</code> injects a <code>LogConfiguration</code> instance automatically by detecting the <code>@ConfigRoot</code>
annotation.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>A corresponding <code>application.properties</code> for the above example could be:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="properties" class="language-properties hljs">quarkus.log.file.enable=true
quarkus.log.file.level=DEBUG
quarkus.log.file.path=/tmp/debug.log</code></pre>
</div>
</div>
<div class="paragraph">
<p>Since <code>format</code> is not defined in these properties, the default value from <code>@ConfigItem</code> will be used instead.</p>
</div>
</div>
<div class="sect3">
<h4 id="enhanced-conversion"><a class="anchor" href="#enhanced-conversion"></a>2.4.8. Enhanced conversion</h4>
<div class="paragraph">
<p>You can use enhanced conversion of a config item by using the <code>@ConvertWith</code> annotation which accepts a <code>Converter</code> class object.
If the annotation is present on a config item, the implicit or custom built in converter in use will be overridden by the value provided.
To do, see the example below which converts <code>YES</code> or <code>NO</code> values to <code>boolean</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@ConfigRoot
public class SomeConfig {
    /**
     * Config item with enhanced converter
     */
    @ConvertWith(YesNoConverter.class) <i class="conum" data-value="1"></i><b>(1)</b>
    @ConfigItem(defaultValue = "NO")
    Boolean answer;


    public static class YesNoConverter implements Converter&lt;Boolean&gt; {

        public YesNoConverter() {}

        @Override
        public Boolean convert(String s) {
            if (s == null || s.isEmpty()) {
                return false;
            }

            switch (s) {
                case "YES":
                    return true;
                case "NO":
                    return false;
            }

            throw new IllegalArgumentException("Unsupported value " + s + " given");
        }
    }
}</code></pre>
</div>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Override the default <code>Boolean</code> converter and use the provided converter which accepts a <code>YES</code> or <code>NO</code> config values.</p>
</li>
</ol>
</div>
<div class="paragraph">
<p>The corresponding <code>application.properties</code> will look like.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="properties" class="language-properties hljs">quarkus.some.answer=YES</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Enum values (config items) are translated to skewed-case (hyphenated) by default. The table below illustrates an enum name and their canonical equivalence:</p>
</div>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 50%;">
<col style="width: 50%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Java enum</th>
<th class="tableblock halign-left valign-top">Canonical equivalent</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">DISCARD</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">discard</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">READ_UNCOMMITTED</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">read-uncommitted</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">SIGUSR1</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">sigusr1</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">JavaEnum</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">java-enum</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">MAKING_LifeDifficult</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">making-life-difficult</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">YeOldeJBoss</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">ye-olde-jboss</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">camelCaseEnum</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">camel-case-enum</p></td>
</tr>
</tbody>
</table>
<div class="paragraph">
<p>To use the default behaviour which is based on implicit converter or a custom defined one add <code>@DefaultConverter</code> annotation to the configuration item</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@ConfigRoot
public class SomeLogConfig {
    /**
     * The level of logs to be written into the file.
     */
    @DefaultConverter <i class="conum" data-value="1"></i><b>(1)</b>
    @ConfigItem(defaultValue = "ALL")
    Level level;
}</code></pre>
</div>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>Use the default converter (built in or a custom converter) to convert <code>Level.class</code> enum.</p>
</li>
</ol>
</div>
</td>
</tr>
</table>
</div>
</div>
</div>
<div class="sect2">
<h3 id="conditional-step-inclusion"><a class="anchor" href="#conditional-step-inclusion"></a>2.5. Conditional Step Inclusion</h3>
<div class="paragraph">
<p>It is possible to only include a given <code>@BuildStep</code> under certain conditions.  The <code>@BuildStep</code> annotation
has two optional parameters: <code>onlyIf</code> and <code>onlyIfNot</code>.  These parameters can be set to one or more classes
which implement <code>BooleanSupplier</code>.  The build step will only be included when the method returns
<code>true</code> (for <code>onlyIf</code>) or <code>false</code> (for <code>onlyIfNot</code>).</p>
</div>
<div class="paragraph">
<p>The condition class can inject <a href="#configuration-roots">configuration roots</a> as long as they belong to
a build-time phase.  Run time configuration is not available for condition classes.</p>
</div>
<div class="paragraph">
<p>The condition class may also inject a value of type <code>io.quarkus.runtime.LaunchMode</code>.
Constructor parameter and field injection is supported.</p>
</div>
<div class="listingblock">
<div class="title">An example of a conditional build step</div>
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep(onlyIf = IsDevMode.class)
LogCategoryBuildItem enableDebugLogging() {
    return new LogCategoryBuildItem("org.your.quarkus.extension", Level.DEBUG);
}

static class IsDevMode implements BooleanSupplier {
    LaunchMode launchMode;

    public boolean getAsBoolean() {
        return launchMode == LaunchMode.DEVELOPMENT;
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="bytecode-recording"><a class="anchor" href="#bytecode-recording"></a>2.6. Bytecode Recording</h3>
<div class="paragraph">
<p>One of the main outputs of the build process is recorded bytecode. This bytecode actually sets up the runtime environment. For example, in order to start Undertow, the resulting application will have some bytecode that directly registers all
Servlet instances and then starts Undertow.</p>
</div>
<div class="paragraph">
<p>As writing bytecode directly is complex, this is instead done via bytecode recorders. At deployment time,
invocations are made on recorder objects that contain the actual runtime logic, but instead of these invocations
proceeding as normal they are intercepted and recorded (hence the name). This recording is then used to generate bytecode
that performs the same sequence of invocations at runtime. This is essentially a form of deferred execution where invocations
made at deployment time get deferred until runtime.</p>
</div>
<div class="paragraph">
<p>Let&#8217;s look at the classic 'Hello World' type example. To do this the Quarkus way we would create a recorder as follows:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Recorder
class HelloRecorder {

  public void sayHello(String name) {
    System.out.println("Hello" + name);
  }

}</code></pre>
</div>
</div>
<div class="paragraph">
<p>And then create a build step that uses this recorder:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@Record(RUNTIME_INIT)
@BuildStep
public void helloBuildStep(HelloRecorder recorder) {
    recorder.sayHello("World");
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>When this build step is run nothing is printed to the console. This is because the <code>HelloRecorder</code> that is injected is
actually a proxy that records all invocations. Instead if we run the resulting Quarkus program we will see 'Hello World'
printed to the console.</p>
</div>
<div class="paragraph">
<p>Methods on a recorder can return a value, which must be proxiable (if you want to return a non-proxiable item wrap it
in <code>io.quarkus.runtime.RuntimeValue</code>). These proxies may not be invoked directly, however they can be passed
into other recorder methods. This can be any recorder method, including from other <code>@BuildStep</code> methods, so a common pattern
is to produce <code>BuildItem</code> instances that wrap the results of these recorder invocations.</p>
</div>
<div class="paragraph">
<p>For instance, in order to make arbitrary changes to a Servlet deployment Undertow has a <code>ServletExtensionBuildItem</code>,
which is a <code>MultiBuildItem</code> that wraps a <code>ServletExtension</code> instance. I can return a <code>ServletExtension</code> from a recorder
in another module, and Undertow will consume it and pass it into the recorder method that starts Undertow.</p>
</div>
<div class="paragraph">
<p>At runtime the bytecode will be invoked in the order it is generated. This means that build step dependencies implicitly
control the order that generated bytecode is run. In the example above we know that the bytecode that produces a
<code>ServletExtensionBuildItem</code> will be run before the bytecode that consumes it.</p>
</div>
<div class="paragraph">
<p>The following objects can be passed to recorders:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Primitives</p>
</li>
<li>
<p>String</p>
</li>
<li>
<p>Class&lt;?&gt; objects</p>
</li>
<li>
<p>Objects returned from a previous recorder invocation</p>
</li>
<li>
<p>Objects with a no-arg constructor and getter/setters for all properties (or public fields)</p>
</li>
<li>
<p>Objects with a constructor annotated with <code>@RecordableConstructor</code> with parameter names that match field names</p>
</li>
<li>
<p>Any arbitrary object via the <code>io.quarkus.deployment.recording.RecorderContext#registerSubstitution(Class, Class, Class)</code> mechanism</p>
</li>
<li>
<p>Arrays, Lists and Maps of the above</p>
</li>
</ul>
</div>
<div class="sect3">
<h4 id="recordercontext"><a class="anchor" href="#recordercontext"></a>2.6.1. RecorderContext</h4>
<div class="paragraph">
<p><code>io.quarkus.deployment.recording.RecorderContext</code> provides some convenience methods to enhance bytecode recording,
this includes the ability to register creation functions for classes without no-arg constructors, to register an object
substitution (basically a transformer from a non-serializable object to a serializable one and vice versa), and to create
a class proxy. This interface can be directly injected as a method parameter into any <code>@Record</code> method.</p>
</div>
<div class="paragraph">
<p>Calling <code>classProxy</code> with a given class name will create a <code>Class</code> that can be passed into recorder
methods, and at runtime will be substituted with the class whose name was passed in to <code>classProxy</code>. This is basically a
convenience to avoid the need to explicitly load classes in the recorders.</p>
</div>
</div>
<div class="sect3">
<h4 id="printing-step-execution-time"><a class="anchor" href="#printing-step-execution-time"></a>2.6.2. Printing step execution time</h4>
<div class="paragraph">
<p>At times, it can be useful to know how the exact time each startup task (which is the result of each bytecode recording) takes when the application is run.
The simplest way to determine this information is to set the <code>quarkus.debug.print-startup-times</code> property to <code>true</code> when running the application.
The output will look something like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code class="language-none hljs">Build step LoggingResourceProcessor.setupLoggingRuntimeInit completed in: 42ms
Build step ConfigGenerationBuildStep.checkForBuildTimeConfigChange completed in: 4ms
Build step SyntheticBeansProcessor.initRuntime completed in: 0ms
Build step ConfigBuildStep.validateConfigProperties completed in: 1ms
Build step ResteasyStandaloneBuildStep.boot completed in: 95ms
Build step VertxHttpProcessor.initializeRouter completed in: 1ms
Build step VertxHttpProcessor.finalizeRouter completed in: 4ms
Build step LifecycleEventsBuildStep.startupEvent completed in: 1ms
Build step VertxHttpProcessor.openSocket completed in: 93ms
Build step ShutdownListenerBuildStep.setupShutdown completed in: 1ms</code></pre>
</div>
</div>
</div>
</div>
<div class="sect2">
<h3 id="contexts-and-dependency-injection"><a class="anchor" href="#contexts-and-dependency-injection"></a>2.7. Contexts and Dependency Injection</h3>
<div class="sect3">
<h4 id="extension-points"><a class="anchor" href="#extension-points"></a>2.7.1. Extension Points</h4>
<div class="paragraph">
<p>As a CDI based runtime, Quarkus extensions often make CDI beans available as part of the extension behavior.
However, Quarkus DI solution does not support CDI Portable Extensions.
Instead, Quarkus extensions can make use of various <a href="cdi-reference">Build Time Extension Points</a>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="extension-health-check"><a class="anchor" href="#extension-health-check"></a>2.8. Extension Health Check</h3>
<div class="paragraph">
<p>Health checks are provided via the <code>quarkus-smallrye-health</code> extension. It provides both liveness and readiness checks capabilities.</p>
</div>
<div class="paragraph">
<p>When writing an extension, it&#8217;s beneficial to provide health checks for the extension, that can be automatically included without the developer needing to write their own.</p>
</div>
<div class="paragraph">
<p>In order to provide a health check, you should do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Import the <code>quarkus-smallrye-health</code> extension as an <strong>optional</strong> dependency in your runtime module so it will not impact the size of the application if
health check is not included.</p>
</li>
<li>
<p>Create your health check following the <a href="microprofile-health">Quarkus - MicroProfile Health</a> guide. We advise providing only
readiness check for an extension (liveness check is designed to express the fact that an application is up and needs to be lightweight).</p>
</li>
<li>
<p>Import the <code>quarkus-smallrye-health-spi</code> library in your deployment module.</p>
</li>
<li>
<p>Add a build step in your deployment module that produces a <code>HealthBuildItem</code>.</p>
</li>
<li>
<p>Add a way to disable the extension health check via a config item <code>quarkus.&lt;extension&gt;.health.enabled</code> that should be enabled by default.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Following is an example from the Agroal extension that provides a <code>DataSourceHealthCheck</code> to validate the readiness of a datasource.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
HealthBuildItem addHealthCheck(AgroalBuildTimeConfig agroalBuildTimeConfig) {
    return new HealthBuildItem("io.quarkus.agroal.runtime.health.DataSourceHealthCheck",
            agroalBuildTimeConfig.healthEnabled);
}</code></pre>
</div>
</div>
</div>
<div class="sect2">
<h3 id="extension-metrics"><a class="anchor" href="#extension-metrics"></a>2.9. Extension Metrics</h3>
<div class="paragraph">
<p>The <code>quarkus-smallrye-metrics</code> extension (and other 3rd party or experimental extensions) provide support for collecting metrics. There are two broad patterns that extensions can use to interact with an optional metrics extension to add their own metrics:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Consumer pattern: An extension declares a <code>MetricsFactoryConsumerBuildItem</code> and uses that to provide a bytecode recorder to the metrics extension. When the metrics extension has initialized, it will iterate over registered consumers to initialize them with a <code>MetricsFactory</code>. This factory can be used to declare API-agnostic metrics, which can be a good fit for extensions that provide an instrumentable object for gathering statistics (e.g. Hibernate&#8217;s <code>Statistics</code> class).</p>
</li>
<li>
<p>Binder pattern: An extension can opt to use completely different gathering implementations depending on the metrics system. An <code>Optional&lt;MetricsCapabilityBuildItem&gt; metricsCapability</code> build step parameter can be used to declare or otherwise initialize API-specific metrics based on the active metrics extension (e.g. "smallrye-metrics" or "micrometer"). This pattern can be combined with the consumer pattern by using <code>MetricsFactory::metricsSystemSupported()</code> to test the active metrics extension within the recorder.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Remember that support for metrics is optional. Extensions can use an <code>Optional&lt;MetricsCapabilityBuildItem&gt; metricsCapability</code> parameter in their build step to test for the presence of an enabled metrics extension. Consider using additional configuration to control behavior of metrics. Datasource metrics can be expensive, for example, so additional configuration flags are used enable metrics collection on individual datasources.</p>
</div>
<div class="paragraph">
<p>When adding metrics for your extension, you may find yourself in one of the following situations:</p>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>An underlying library used by the extension is using a specific Metrics API directly (either MP Metrics, micrometer, or some other).</p>
</li>
<li>
<p>An underlying library uses its own mechanism for collecting metrics and makes them available at runtime using its own API, e.g. Hibernate&#8217;s <code>Statistics</code> class, or Vert.x <code>MetricsOptions</code>.</p>
</li>
<li>
<p>An underlying library does not provide metrics (or there is no library at all) and you want to add instrumentation.</p>
</li>
</ol>
</div>
<div class="sect3">
<h4 id="case-1-the-library-uses-a-metrics-library-directly"><a class="anchor" href="#case-1-the-library-uses-a-metrics-library-directly"></a>2.9.1. Case 1: The library uses a metrics library directly</h4>
<div class="paragraph">
<p>If the library directly uses a metrics API, there are two options:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Use an <code>Optional&lt;MetricsCapabilityBuildItem&gt; metricsCapability</code> parameter to test which metrics API is supported (e.g. "smallrye-metrics" or "micrometer") in your build step, and use that to selectively declare or initialize API-specific beans or build items.</p>
</li>
<li>
<p>Create a separate build step that consumes a <code>MetricsFactory</code>, and use the <code>MetricsFactory::metricsSystemSupported()</code> method within the bytecode recorder to initialize required resources if the desired metrics API is supported (e.g. "smallrye-metrics" or "micrometer").</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>Extensions may need to provide a fallback if there is no active metrics extension or the extension doesn&#8217;t support the API required by the library.</p>
</div>
</div>
<div class="sect3">
<h4 id="case-2-the-library-provides-its-own-metric-api"><a class="anchor" href="#case-2-the-library-provides-its-own-metric-api"></a>2.9.2. Case 2: The library provides its own metric API</h4>
<div class="paragraph">
<p>There are two examples of a library providing its own metrics API:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>The extension defines an instrumentable object as Agroal does with <code>io.agroal.api.AgroalDataSourceMetrics</code>, or</p>
</li>
<li>
<p>The extension provides its own abstraction of metrics, as Jaeger does with <code>io.jaegertracing.spi.MetricsFactory</code>.</p>
</li>
</ul>
</div>
<div class="sect4">
<h5 id="observing-instrumentable-objects"><a class="anchor" href="#observing-instrumentable-objects"></a>2.9.2.1. Observing instrumentable objects</h5>
<div class="paragraph">
<p>Let&#8217;s take the instrumentable object (<code>io.agroal.api.AgroalDataSourceMetrics</code>) case first. In this case, you can do the following:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Define a <code>BuildStep</code> that produces a <code>MetricsFactoryConsumerBuildItem</code> that uses a <code>RUNTIME_INIT</code> or <code>STATIC_INIT</code> Recorder to define a <code>MetricsFactory</code> consumer. For example, the following creates a <code>MetricsFactoryConsumerBuildItem</code> if and only if metrics are enabled both for Agroal generally, and for a datasource specifically:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void registerMetrics(AgroalMetricsRecorder recorder,
        DataSourcesBuildTimeConfig dataSourcesBuildTimeConfig,
        BuildProducer&lt;MetricsFactoryConsumerBuildItem&gt; datasourceMetrics,
        List&lt;AggregatedDataSourceBuildTimeConfigBuildItem&gt; aggregatedDataSourceBuildTimeConfigs) {

    for (AggregatedDataSourceBuildTimeConfigBuildItem aggregatedDataSourceBuildTimeConfig : aggregatedDataSourceBuildTimeConfigs) {
        // Create a MetricsFactory consumer to register metrics for a data source
        // IFF metrics are enabled globally and for the data source
        // (they are enabled for each data source by default if they are also enabled globally)
        if (dataSourcesBuildTimeConfig.metricsEnabled &amp;&amp;
                aggregatedDataSourceBuildTimeConfig.getJdbcConfig().enableMetrics.orElse(true)) {
            datasourceMetrics.produce(new MetricsFactoryConsumerBuildItem(
                    recorder.registerDataSourceMetrics(aggregatedDataSourceBuildTimeConfig.getName())));
        }
    }
}</code></pre>
</div>
</div>
</li>
<li>
<p>The associated recorder should use the provided <code>MetricsFactory</code> to register metrics. For Agroal, this means using the <code>MetricFactory</code> API to observe <code>io.agroal.api.AgroalDataSourceMetrics</code> methods. For example:</p>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/* RUNTIME_INIT */
public Consumer&lt;MetricsFactory&gt; registerDataSourceMetrics(String dataSourceName) {
    return new Consumer&lt;MetricsFactory&gt;() {
        @Override
        public void accept(MetricsFactory metricsFactory) {
            String tagValue = DataSourceUtil.isDefault(dataSourceName) ? "default" : dataSourceName;
            AgroalDataSourceMetrics metrics = getDataSource(dataSourceName).getMetrics();

            // When using MP Metrics, the builder uses the VENDOR registry by default.
            metricsFactory.builder("agroal.active.count")
                    .description(
                            "Number of active connections. These connections are in use and not available to be acquired.")
                    .tag("datasource", tagValue)
                    .buildGauge(metrics::activeCount);
            ....</code></pre>
</div>
</div>
</li>
</ul>
</div>
<div class="paragraph">
<p>The <code>MetricsFactory</code> provides a fluid builder for registration of metrics, with the final step constructing gauges or counters based on a <code>Supplier</code> or <code>ToDoubleFunction</code>. Timers can either wrap <code>Callable</code>, <code>Runnable</code>, or <code>Supplier</code> implementations, or can use a <code>TimeRecorder</code> to accumulate chunks of time. The underlying metrics extension will create appropriate artifacts to observe or measure the defined functions.</p>
</div>
</div>
<div class="sect4">
<h5 id="using-a-metrics-api-specific-implementation"><a class="anchor" href="#using-a-metrics-api-specific-implementation"></a>2.9.2.2. Using a Metrics API-specific implementation</h5>
<div class="paragraph">
<p>Using metrics-API specific implementations may be preferred in some cases.nJaeger, for example, defines its own metrics interface, <code>io.jaegertracing.spi.MetricsFactory</code>, that it uses to define counters and gauges. A direct mapping from that interface to the metrics system will be the most efficient. In this case, it is important to isolate these specialized implementations and to avoid eager classloading to ensure the metrics API remains an optional, compile-time dependency.</p>
</div>
<div class="paragraph">
<p><code>Optional&lt;MetricsCapabilityBuildItem&gt; metricsCapability</code> can be used in the build step to selectively control initialization of beans or the production of other build items. The Jaeger extension, for example, can use the following to control initialization of specialized Metrics API adapters:</p>
</div>
<div class="paragraph">
<p>+</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">/* RUNTIME_INIT */
@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
void setupTracer(JaegerDeploymentRecorder jdr, JaegerBuildTimeConfig buildTimeConfig, JaegerConfig jaeger,
        ApplicationConfig appConfig, Optional&lt;MetricsCapabilityBuildItem&gt; metricsCapability) {

    // Indicates that this extension would like the SSL support to be enabled
    extensionSslNativeSupport.produce(new ExtensionSslNativeSupportBuildItem(Feature.JAEGER.getName()));

    if (buildTimeConfig.enabled) {
        boolean metricsEnabled = buildTimeConfig.metricsEnabled &amp;&amp; metricsCapability.isPresent();
        if ( metricsEnabled &amp;&amp; metricsCapability.get().metricsSupported(MetricsFactory.MP_METRICS)) {
            jdr.registerTracerWithMpMetrics(jaeger, appConfig);
        } else if ( metricsEnabled &amp;&amp; metricsCapability.get().metricsSupported(MetricsFactory.MICROMETER)) {
            jdr.registerTracerWithMicrometer(jaeger, appConfig);
        } else {
            jdr.registerTracerWithoutMetrics(jaeger, appConfig);
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>A recorder consuming a <code>MetricsFactory</code> can use <code>MetricsFactory::metricsSystemSupported()</code> can be used to control initialization of metrics objects during bytecode recording in a similar way.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="case-3-it-is-necessary-to-collect-metrics-within-the-extension-code"><a class="anchor" href="#case-3-it-is-necessary-to-collect-metrics-within-the-extension-code"></a>2.9.3. Case 3: It is necessary to collect metrics within the extension code</h4>
<div class="paragraph">
<p>To define your own metrics from scratch, you have two basic options: Use the generic <code>MetricFactory</code> builders, or follow the binder pattern, and create instrumentation specific to the enabled metrics extension.</p>
</div>
<div class="paragraph">
<p>To use the extension-agnostic <code>MetricFactory</code> API, your processor can define a <code>BuildStep</code> that produces a <code>MetricsFactoryConsumerBuildItem</code> that uses a <code>RUNTIME_INIT</code> or <code>STATIC_INIT</code> Recorder to define a <code>MetricsFactory</code> consumer.</p>
</div>
<div class="paragraph">
<p>+</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
MetricsFactoryConsumerBuildItem registerMetrics(MyExtensionRecorder recorder) {
    return new MetricsFactoryConsumerBuildItem(recorder.registerMetrics());
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>+
- The associated recorder should use the provided <code>MetricsFactory</code> to register metrics, for example</p>
</div>
<div class="paragraph">
<p>+</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">final LongAdder extensionCounter = new LongAdder();

/* RUNTIME_INIT */
public Consumer&lt;MetricsFactory&gt; registerMetrics() {
    return new Consumer&lt;MetricsFactory&gt;() {
        @Override
        public void accept(MetricsFactory metricsFactory) {
            metricsFactory.builder("my.extension.counter")
                    .buildGauge(extensionCounter::longValue);
            ....</code></pre>
</div>
</div>
<div class="paragraph">
<p>Remember that metrics extensions are optional. Keep metrics-related initialization isolated from other setup for your extension, and structure your code to avoid eager imports of metrics APIs.</p>
</div>
<div class="paragraph">
<p>Gathering metrics can be expensive. Consider using additional extension-specific configuration to control behavior of metrics if the presence/absence of metrics support isn&#8217;t sufficient. Datasource metrics can be expensive, for example, so there are additional flags to selectively enable collection of metrics on datasources.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="customizing-json-handling-from-an-extension"><a class="anchor" href="#customizing-json-handling-from-an-extension"></a>2.10. Customizing JSON handling from an extension</h3>
<div class="paragraph">
<p>Extensions often need to register serializers and/or deserializers for types the extension provides.</p>
</div>
<div class="paragraph">
<p>For this, both JSON-B and Jackson extension provide a way to register serializer/deserializer from within an
extension deployment module.</p>
</div>
<div class="paragraph">
<p>Keep in mind that not everybody will need JSON, so you need to make it optional.</p>
</div>
<div class="paragraph">
<p>If an extension intends to provide JSON related customization,
it is strongly advised to provide customization for both JSON-B and Jackson.</p>
</div>
<div class="sect3">
<h4 id="customizing-json-b"><a class="anchor" href="#customizing-json-b"></a>2.10.1. Customizing JSON-B</h4>
<div class="paragraph">
<p>First, add an <strong>optional</strong> dependency to <code>quarkus-jsonb</code> on your extension&#8217;s runtime module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-jsonb&lt;/artifactId&gt;
  &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then create a serializer and/or a deserializer for JSON-B, an example of which can be seen in the <code>mongodb-panache</code> extension.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">public class ObjectIdSerializer implements JsonbSerializer&lt;ObjectId&gt; {
    @Override
    public void serialize(ObjectId obj, JsonGenerator generator, SerializationContext ctx) {
        if (obj != null) {
            generator.write(obj.toString());
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add a dependency to <code>quarkus-jsonb-spi</code> on your extension&#8217;s deployment module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-jsonb-spi&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add a build step to your processor to register the serializer via the <code>JsonbSerializerBuildItem</code>.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
JsonbSerializerBuildItem registerJsonbSerializer() {
    return new JsonbSerializerBuildItem(io.quarkus.mongodb.panache.jsonb.ObjectIdSerializer.class.getName()));
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The JSON-B extension will then use the produced build item to register your serializer/deserializer automatically.</p>
</div>
<div class="paragraph">
<p>If you need more customization capabilities than registering a serializer or a deserializer,
you can produce a CDI bean that implements <code>io.quarkus.jsonb.JsonbConfigCustomizer</code> via an <code>AdditionalBeanBuildItem</code>.
More info about customizing JSON-B can be found on the JSON guide <a href="rest-json#configuring-json-support">Configuring JSON support</a></p>
</div>
</div>
<div class="sect3">
<h4 id="customizing-jackson"><a class="anchor" href="#customizing-jackson"></a>2.10.2. Customizing Jackson</h4>
<div class="paragraph">
<p>First, add an <strong>optional</strong> dependency to <code>quarkus-jackson</code> on your extension&#8217;s runtime module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-jackson&lt;/artifactId&gt;
  &lt;optional&gt;true&lt;/optional&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then create a serializer or a deserializer (or both) for Jackson, an example of which can be seen in the <code>mongodb-panache</code> extension.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">public class ObjectIdSerializer extends StdSerializer&lt;ObjectId&gt; {
    public ObjectIdSerializer() {
        super(ObjectId.class);
    }
    @Override
    public void serialize(ObjectId objectId, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        if (objectId != null) {
            jsonGenerator.writeString(objectId.toString());
        }
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add a dependency to <code>quarkus-jackson-spi</code> on your extension&#8217;s deployment module.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="xml" class="language-xml hljs">&lt;dependency&gt;
  &lt;groupId&gt;io.quarkus&lt;/groupId&gt;
  &lt;artifactId&gt;quarkus-jackson-spi&lt;/artifactId&gt;
&lt;/dependency&gt;</code></pre>
</div>
</div>
<div class="paragraph">
<p>Add a build step to your processor to register a Jackson module via the <code>JacksonModuleBuildItem</code>.
You need to name your module in a unique way across all Jackson modules.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight nowrap"><code data-lang="java" class="language-java hljs">@BuildStep
JacksonModuleBuildItem registerJacksonSerDeser() {
    return new JacksonModuleBuildItem.Builder("ObjectIdModule")
                    .add(io.quarkus.mongodb.panache.jackson.ObjectIdSerializer.class.getName(),
                            io.quarkus.mongodb.panache.jackson.ObjectIdDeserializer.class.getName(),
                            ObjectId.class.getName())
                    .build();
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>The Jackson extension will then use the produced build item to register a module within Jackson automatically.</p>
</div>
<div class="paragraph">
<p>If you need more customization capabilities than registering a module,
you can produce a CDI bean that implements <code>io.quarkus.jackson.ObjectMapperCustomizer</code> via an <code>AdditionalBeanBuildItem</code>.
More info about customizing Jackson can be found on the JSON guide <a href="rest-json#configuring-json-support">Configuring JSON support</a></p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="testing-extensions"><a class="anchor" href="#testing-extensions"></a>2.11. Testing Extensions</h3>
<div class="paragraph">
<p>Testing of Quarkus extensions should be done with the <code>io.quarkus.test.QuarkusUnitTest</code> JUnit 5 extension.
This extension allows for Arquillian-style tests that test specific functionalities.
It is not intended for testing user applications, as this should be done via <code>io.quarkus.test.junit.QuarkusTest</code>.
The main difference is that <code>QuarkusTest</code> simply boots the application once at the start of the run, while <code>QuarkusUnitTest</code> deploys a custom
Quarkus application for each test class.</p>
</div>
<div class="paragraph">
<p>These tests should be placed in the deployment module, if additional Quarkus modules are required for testing
their deployment modules should also be added as test scoped dependencies.</p>
</div>
<div class="paragraph">
<p>Note that <code>QuarkusUnitTest</code> is in the <code>quarkus-junit5-internal</code> module.</p>
</div>
<div class="paragraph">
<p>An example test class may look like:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package io.quarkus.health.test;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.ArrayList;
import java.util.List;

import javax.enterprise.inject.Instance;
import javax.inject.Inject;

import org.eclipse.microprofile.health.Health;
import org.eclipse.microprofile.health.HealthCheck;
import org.eclipse.microprofile.health.HealthCheckResponse;
import io.quarkus.test.QuarkusUnitTest;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.restassured.RestAssured;

public class FailingUnitTest {

    @RegisterExtension                                                                  <i class="conum" data-value="1"></i><b>(1)</b>
    static final QuarkusUnitTest config = new QuarkusUnitTest()
            .setArchiveProducer(() -&gt;
                    ShrinkWrap.create(JavaArchive.class)                                <i class="conum" data-value="2"></i><b>(2)</b>
                            .addClasses(FailingHealthCheck.class)
                            .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")
            );

    @Inject                                                                             <i class="conum" data-value="3"></i><b>(3)</b>
    @Health
    Instance&lt;HealthCheck&gt; checks;

    @Test
    public void testHealthServlet() {
        RestAssured.when().get("/health").then().statusCode(503);                       <i class="conum" data-value="4"></i><b>(4)</b>
    }

    @Test
    public void testHealthBeans() {
        List&lt;HealthCheck&gt; check = new ArrayList&lt;&gt;();                                    <i class="conum" data-value="5"></i><b>(5)</b>
        for (HealthCheck i : checks) {
            check.add(i);
        }
        assertEquals(1, check.size());
        assertEquals(HealthCheckResponse.State.DOWN, check.get(0).call().getState());
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The <code>QuarkusUnitTest</code> extension must be used with a static field. If used with a non-static field, the test application is not started.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This producer is used to build the application to be tested. It uses Shrinkwrap to create a JavaArchive to test</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>It is possible to inject beans from our test deployment directly into the test case</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>This method directly invokes the health check Servlet and verifies the response</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>This method uses the injected health check bean to verify it is returning the expected result</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>If you want to test that an extension properly fails at build time, use the <code>setExpectedException</code> method:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package io.quarkus.hibernate.orm;

import io.quarkus.deployment.configuration.ConfigurationError;
import io.quarkus.test.QuarkusUnitTest;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

public class PersistenceAndQuarkusConfigTest {

    @RegisterExtension
    static QuarkusUnitTest runner = new QuarkusUnitTest()
            .setExpectedException(ConfigurationError.class)                     <i class="conum" data-value="1"></i><b>(1)</b>
            .setArchiveProducer(() -&gt; ShrinkWrap.create(JavaArchive.class)
                    .addAsManifestResource("META-INF/some-persistence.xml", "persistence.xml")
                    .addAsResource("application.properties"));

    @Test
    public void testPersistenceAndConfigTest() {
        // should not be called, deployment exception should happen first:
        // it's illegal to have Hibernate configuration properties in both the
        // application.properties and in the persistence.xml
        Assertions.fail();
    }

}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This tells JUnit that the Quarkus deployment should fail with a specific exception</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="testing-hot-reload"><a class="anchor" href="#testing-hot-reload"></a>2.12. Testing hot reload</h3>
<div class="paragraph">
<p>It is also possible to write tests that verify an extension works correctly in development mode and can correctly
handle updates.</p>
</div>
<div class="paragraph">
<p>For most extensions this will just work 'out of the box', however it is still a good idea to have a smoke test to
verify that this functionality is working as expected. To test this we use <code>QuarkusDevModeTest</code>:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public class ServletChangeTestCase {

    @RegisterExtension
    final static QuarkusDevModeTest test = new QuarkusDevModeTest()
            .setArchiveProducer(new Supplier&lt;JavaArchive&gt;() {
                @Override
                public JavaArchive get() {
                    return ShrinkWrap.create(JavaArchive.class)   <i class="conum" data-value="1"></i><b>(1)</b>
                            .addClass(DevServlet.class)
                            .addAsManifestResource(new StringAsset("Hello Resource"), "resources/file.txt");
                }
            });

    @Test
    public void testServletChange() throws InterruptedException {
        RestAssured.when().get("/dev").then()
                .statusCode(200)
                .body(is("Hello World"));

        test.modifySourceFile("DevServlet.java", new Function&lt;String, String&gt;() {  <i class="conum" data-value="2"></i><b>(2)</b>

            @Override
            public String apply(String s) {
                return s.replace("Hello World", "Hello Quarkus");
            }
        });

        RestAssured.when().get("/dev").then()
                .statusCode(200)
                .body(is("Hello Quarkus"));
    }

    @Test
    public void testAddServlet() throws InterruptedException {
        RestAssured.when().get("/new").then()
                .statusCode(404);

        test.addSourceFile(NewServlet.class);                                       <i class="conum" data-value="3"></i><b>(3)</b>

        RestAssured.when().get("/new").then()
                .statusCode(200)
                .body(is("A new Servlet"));
    }

    @Test
    public void testResourceChange() throws InterruptedException {
        RestAssured.when().get("/file.txt").then()
                .statusCode(200)
                .body(is("Hello Resource"));

        test.modifyResourceFile("META-INF/resources/file.txt", new Function&lt;String, String&gt;() { <i class="conum" data-value="4"></i><b>(4)</b>

            @Override
            public String apply(String s) {
                return "A new resource";
            }
        });

        RestAssured.when().get("file.txt").then()
                .statusCode(200)
                .body(is("A new resource"));
    }

    @Test
    public void testAddResource() throws InterruptedException {

        RestAssured.when().get("/new.txt").then()
                .statusCode(404);

        test.addResourceFile("META-INF/resources/new.txt", "New File");  <i class="conum" data-value="5"></i><b>(5)</b>

        RestAssured.when().get("/new.txt").then()
                .statusCode(200)
                .body(is("New File"));

    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>This starts the deployment, your test can modify it as part of the test suite. Quarkus will be restarted between
each test method so every method starts with a clean deployment.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>This method allows you to modify the source of a class file. The old source is passed into the function, and the updated
source is returned.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>This method adds a new class file to the deployment. The source that is used will be the original source that is part
of the current project.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>This method modifies a static resource</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>This method adds a new static resource</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="native-executable-support"><a class="anchor" href="#native-executable-support"></a>2.13. Native Executable Support</h3>
<div class="paragraph">
<p>There Quarkus provides a lot of build items that control aspects of the native executable build. This allows for extensions
to programmatically perform tasks such as registering classes for reflection or adding static resources to the native
executable. Some of these build items are listed below:</p>
</div>
<div class="dlist">
<dl>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem</code></dt>
<dd>
<p>Includes static resources into the native executable.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.NativeImageResourceDirectoryBuildItem</code></dt>
<dd>
<p>Includes directory&#8217;s static resources into the native executable.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.RuntimeReinitializedClassBuildItem</code></dt>
<dd>
<p>A class that will be reinitialized at runtime by Substrate. This will result in the static initializer running twice.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.NativeImageSystemPropertyBuildItem</code></dt>
<dd>
<p>A system property that will be set at native executable build time.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBundleBuildItem</code></dt>
<dd>
<p>Includes a resource bundle in the native executable.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem</code></dt>
<dd>
<p>Registers a class for reflection in Substrate. Constructors are always registered, while methods and fields are optional.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.RuntimeInitializedClassBuildItem</code></dt>
<dd>
<p>A class that will be initialized at runtime rather than build time. This will cause the build to fail if the class is initialized as part of the native executable build process, so care must be taken.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.nativeimage.NativeImageConfigBuildItem</code></dt>
<dd>
<p>A convenience feature that allows you to control most of the above features from a single build item.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.NativeImageEnableAllCharsetsBuildItem</code></dt>
<dd>
<p>Indicates that all charsets should be enabled in native image.</p>
</dd>
<dt class="hdlist1"><code>io.quarkus.deployment.builditem.ExtensionSslNativeSupportBuildItem</code></dt>
<dd>
<p>A convenient way to tell Quarkus that the extension requires SSL and it should be enabled during native image build.
When using this feature, remember to add your extension to the list of extensions that offer SSL support automatically on the <a href="https://github.com/quarkusio/quarkus/blob/master/docs/src/main/asciidoc/native-and-ssl.adoc">native and ssl guide</a>.</p>
</dd>
</dl>
</div>
</div>
<div class="sect2">
<h3 id="ide-support-tips"><a class="anchor" href="#ide-support-tips"></a>2.14. IDE support tips</h3>
<div class="sect3">
<h4 id="writing-quarkus-extensions-in-eclipse"><a class="anchor" href="#writing-quarkus-extensions-in-eclipse"></a>2.14.1. Writing Quarkus extensions in Eclipse</h4>
<div class="paragraph">
<p>The only particular aspect of writing Quarkus extensions in Eclipse is that APT (Annotation Processing Tool) is required as part of extension builds, which means you need to:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Install <code>m2e-apt</code> from <a href="https://marketplace.eclipse.org/content/m2e-apt" class="bare">https://marketplace.eclipse.org/content/m2e-apt</a></p>
</li>
<li>
<p>Define this property in your <code>pom.xml</code>: <code>&lt;m2e.apt.activation&gt;jdt_apt&lt;/m2e.apt.activation&gt;</code>, although if you rely on <code>io.quarkus:quarkus-build-parent</code> you will get it for free.</p>
</li>
<li>
<p>If you have the <code>io.quarkus:quarkus-extension-processor</code> project open at the same time in your IDE (for example, if you have the Quarkus sources checked out and open in your IDE) you will need to close that project. Otherwise, Eclipse will not invoke the APT plugin that it contains.</p>
</li>
<li>
<p>If you just closed the extension processor project, be sure to do <code>Maven &gt; Update Project</code> on the other projects in order for Eclipse to pick up the extension processor from the Maven repository.</p>
</li>
</ul>
</div>
</div>
</div>
<div class="sect2">
<h3 id="troubleshooting-debugging-tips"><a class="anchor" href="#troubleshooting-debugging-tips"></a>2.15. Troubleshooting / Debugging Tips</h3>
<div class="sect3">
<h4 id="dump-the-generated-classes-to-the-file-system"><a class="anchor" href="#dump-the-generated-classes-to-the-file-system"></a>2.15.1. Dump the Generated Classes to the File System</h4>
<div class="paragraph">
<p>During the augmentation phase Quarkus extensions generate new and modify existing classes for various purposes.
Sometimes you need to inspect the generated bytecode to debug or understand an issue.
There are three system properties that allow you to dump the classes to the filesystem:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>quarkus.debug.generated-classes-dir</code> - to dump the generated classes, such as bean metadata</p>
</li>
<li>
<p><code>quarkus.debug.transformed-classes-dir</code> - to dump the transformed classes, e.g. Panache entities</p>
</li>
<li>
<p><code>quarkus.debug.generated-sources-dir</code> - to dump the ZIG files; ZIG file is a textual representation of the generated code that is referenced in the stack traces</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>These properties are especially useful in the development mode or when running the tests where the generated/transformed classes are only held in memory in a class loader.</p>
</div>
<div class="paragraph">
<p>For example, you can specify the <code>quarkus.debug.generated-classes-dir</code> system property to have these classes written out to disk for inspection in the development mode:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw quarkus:dev -Dquarkus.debug.generated-classes-dir=dump-classes</code></pre>
</div>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
The property value could be either an absolute path, such as <code>/home/foo/dump</code> on a Linux machine, or a path relative to the user working directory, i.e. <code>dump</code> corresponds to the <code>{user.dir}/target/dump</code> in the dev mode and <code>{user.dir}/dump</code> when running the tests.
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>You should see a line in the log for each class written to the directory:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">INFO  [io.qua.run.boo.StartupActionImpl] (main) Wrote /path/to/my/app/target/dump-classes/io/quarkus/arc/impl/ActivateRequestContextInterceptor_Bean.class</code></pre>
</div>
</div>
<div class="paragraph">
<p>The property is also honored when running tests:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw clean test -Dquarkus.debug.generated-classes-dir=target/dump-generated-classes</code></pre>
</div>
</div>
<div class="paragraph">
<p>Analogously, you can use the <code>quarkus.debug.transformed-classes-dir</code> and <code>quarkus.debug.transformed-classes-dir</code> properties to dump the relevant output.</p>
</div>
</div>
<div class="sect3">
<h4 id="multi-module-maven-projects-and-the-development-mode"><a class="anchor" href="#multi-module-maven-projects-and-the-development-mode"></a>2.15.2. Multi-module Maven Projects and the Development Mode</h4>
<div class="paragraph">
<p>It&#8217;s not uncommon to develop an extension in a multi-module Maven project that also contains an "example" module.
However, if you want to run the example in the development mode then the <code>-DnoDeps</code> system property must be used in order to exclude the local project dependencies.
Otherwise, Quarkus attempts to monitor the extension classes and this may result in weird class loading issues.</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">./mvnw compile quarkus:dev -DnoDeps</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="indexer-does-not-include-your-external-dependency"><a class="anchor" href="#indexer-does-not-include-your-external-dependency"></a>2.15.3. Indexer does not include your external dependency</h4>
<div class="paragraph">
<p>Remember to add <code>IndexDependencyBuildItem</code> artifacts to your <code>@BuildStep</code>.</p>
</div>
</div>
</div>
<div class="sect2">
<h3 id="sample-test-extension"><a class="anchor" href="#sample-test-extension"></a>2.16. Sample Test Extension</h3>
<div class="paragraph">
<p>We have an extension that is used to test for regressions in the extension processing. It is located in <a href="https://github.com/quarkusio/quarkus/tree/master/core/test-extension" class="bare">https://github.com/quarkusio/quarkus/tree/master/core/test-extension</a> directory. In this section we touch on some of the tasks an extension
author will typically need to perform using the test-extension code to illustrate how the task could be done.</p>
</div>
<div class="sect3">
<h4 id="features-and-capabilities"><a class="anchor" href="#features-and-capabilities"></a>2.16.1. Features and Capabilities</h4>
<div class="sect4">
<h5 id="features"><a class="anchor" href="#features"></a>2.16.1.1. Features</h5>
<div class="paragraph">
<p>A <em>feature</em> represents a functionality provided by an extension.
The name of the feature gets displayed in the log during application bootstrap.</p>
</div>
<div class="listingblock">
<div class="title">Example Startup Lines</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">2019-03-22 14:02:37,884 INFO  [io.quarkus] (main) Quarkus 999-SNAPSHOT started in 0.061s.
2019-03-22 14:02:37,884 INFO  [io.quarkus] (main) Installed features: [cdi, test-extension] <i class="conum" data-value="1"></i><b>(1)</b></code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>A list of features installed in the runtime image</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>A feature can be registered in a <a href="#build-step-processors">Build Step Processors</a> method that produces a <code>FeatureBuildItem</code>:</p>
</div>
<div class="listingblock">
<div class="title">TestProcessor#feature()</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">    @BuildStep
    FeatureBuildItem feature() {
        return new FeatureBuildItem("test-extension");
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>The name of the feature should only contain lowercase characters, words are separated by dash; e.g. <code>security-jpa</code>.
An extension should provide at most one feature and the name must be unique.
If multiple extensions register a feature of the same name the build fails.</p>
</div>
<div class="paragraph">
<p>The feature name should also map to a label in the extension&#8217;s <code>devtools/common/src/main/filtered/extensions.json</code> entry so that
the feature name displayed by the startup line matches a label that one can used to select the extension when creating a project
using the Quarkus maven plugin as shown in this example taken from the <a href="rest-json">Writing JSON REST Services</a> guide where the <code>resteasy-jsonb</code> feature is referenced:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="shell" class="language-shell hljs">mvn io.quarkus:quarkus-maven-plugin:1.7.0.Final:create \
    -DprojectGroupId=org.acme \
    -DprojectArtifactId=rest-json \
    -DclassName="org.acme.rest.json.FruitResource" \
    -Dpath="/fruits" \
    -Dextensions="resteasy-jsonb"
cd rest-json</code></pre>
</div>
</div>
</div>
<div class="sect4">
<h5 id="capabilities-2"><a class="anchor" href="#capabilities-2"></a>2.16.1.2. Capabilities</h5>
<div class="paragraph">
<p>A <em>capability</em> represents a technical capability that can be queried by other extensions.
An extension may provide multiple capabilities and multiple extensions can provide the same capability.
By default, capabilities are not displayed to users.</p>
</div>
<div class="paragraph">
<p>Capabilities can be registered in a <a href="#build-step-processors">Build Step Processors</a> method that produces a <code>CapabilityBuildItem</code>:</p>
</div>
<div class="listingblock">
<div class="title">TestProcessor#capability()</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">    @BuildStep
    void capabilities(BuildProducer&lt;CapabilityBuildItem&gt; capabilityProducer) {
        capabilityProducer.produce(new CapabilityBuildItem("org.acme.test-transactions"));
        capabilityProducer.produce(new CapabilityBuildItem("org.acme.test-metrics"));
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Extensions can consume registered capabilities using the <code>Capabilities</code> build item:</p>
</div>
<div class="listingblock">
<div class="title">TestProcessor#doSomeCoolStuff()</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">    @BuildStep
    void doSomeCoolStuff(Capabilities capabilities) {
        if (capabilities.isPresent(Capability.TRANSACTIONS)) {
          // do something only if JTA transactions are in...
        }
    }</code></pre>
</div>
</div>
<div class="paragraph">
<p>Capabilities should follow the naming conventions of Java packages; e.g. <code>io.quarkus.security.jpa</code>.
Capabilities provided by core extensions should be listed in the <code>io.quarkus.deployment.Capability</code> enum and their name should always start with the <code>io.quarkus</code> prefix.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="bean-defining-annotations"><a class="anchor" href="#bean-defining-annotations"></a>2.16.2. Bean Defining Annotations</h4>
<div class="paragraph">
<p>The CDI layer processes CDI beans that are either explicitly registered or that it discovers based on bean defining annotations as defined in <a href="http://docs.jboss.org/cdi/spec/2.0/cdi-spec.html#bean_defining_annotations">2.5.1. Bean defining annotations</a>. You can expand this set of annotations to include annotations your extension processes using a <code>BeanDefiningAnnotationBuildItem</code> as shown in this <code>TestProcessor#registerBeanDefinningAnnotations</code> example:</p>
</div>
<div class="listingblock">
<div class="title">Register a Bean Definining Annotation</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import javax.enterprise.context.ApplicationScoped;
import org.jboss.jandex.DotName;
import io.quarkus.extest.runtime.TestAnnotation;

public final class TestProcessor {
    static DotName TEST_ANNOTATION = DotName.createSimple(TestAnnotation.class.getName());
    static DotName TEST_ANNOTATION_SCOPE = DotName.createSimple(ApplicationScoped.class.getName());

...

    @BuildStep
    BeanDefiningAnnotationBuildItem registerX() {
        <i class="conum" data-value="1"></i><b>(1)</b>
        return new BeanDefiningAnnotationBuildItem(TEST_ANNOTATION, TEST_ANNOTATION_SCOPE);
    }
...
}

/**
 * Marker annotation for test configuration target beans
 */
@Target({ TYPE })
@Retention(RUNTIME)
@Documented
@Inherited
public @interface TestAnnotation {
}

/**
 * A sample bean
 */
@TestAnnotation <i class="conum" data-value="2"></i><b>(2)</b>
public class ConfiguredBean implements IConfigConsumer {

...</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Register the annotation class and CDI default scope using the Jandex <code>DotName</code> class.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td><code>ConfiguredBean</code> will be processed by the CDI layer the same as a bean annotated with the CDI standard @ApplicationScoped.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="parsing-config-to-objects"><a class="anchor" href="#parsing-config-to-objects"></a>2.16.3. Parsing Config to Objects</h4>
<div class="paragraph">
<p>One of the main things an extension is likely to do is completely separate the configuration phase of behavior from the runtime phase. Frameworks often do parsing/load of configuration on startup that can be done during build time to both reduce the runtime dependencies on frameworks like xml parsers as well as reducing the startup time the parsing incurs.</p>
</div>
<div class="paragraph">
<p>An example of parsing a XML config file using JAXB is shown in the <code>TestProcessor#parseServiceXmlConfig</code> method:
.Parsing an XML Configuration into Runtime XmlConfig Instance</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">    @BuildStep
    @Record(STATIC_INIT)
    RuntimeServiceBuildItem parseServiceXmlConfig(TestRecorder recorder) throws JAXBException {
        RuntimeServiceBuildItem serviceBuildItem = null;
        JAXBContext context = JAXBContext.newInstance(XmlConfig.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        InputStream is = getClass().getResourceAsStream("/config.xml"); <i class="conum" data-value="1"></i><b>(1)</b>
        if (is != null) {
            log.info("Have XmlConfig, loading");
            XmlConfig config = (XmlConfig) unmarshaller.unmarshal(is); <i class="conum" data-value="2"></i><b>(2)</b>
...
        }
        return serviceBuildItem;
    }</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Look for a config.xml classpath resource</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>If found, parse using JAXB context for <code>XmlConfig.class</code></td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If there was no /config.xml resource available in the build environment, then a null <code>RuntimeServiceBuildItem</code> would be returned and no subsequent logic based on a <code>RuntimeServiceBuildItem</code> being produced would execute.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>Typically one is loading a configuration to create some runtime component/service as <code>parseServiceXmlConfig</code> is doing. We will come back to the rest of the behavior in <code>parseServiceXmlConfig</code> in the following <a href="#manage-non-cdi-service">Manage Non-CDI Service</a> section.</p>
</div>
<div class="paragraph">
<p>If for some reason you need to parse the config and use it in other build steps in an extension processor, you would need to create an <code>XmlConfigBuildItem</code> to pass the parsed XmlConfig instance around.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>If you look at the XmlConfig code you will see that it does carry around the JAXB annotations. If you don&#8217;t want these in the runtime image, you could clone the XmlConfig instance into some POJO object graph and then replace XmlConfig with the POJO class. We will do this in <a href="#replacing-classes-in-the-native-image">Replacing Classes in the Native Image</a>.</p>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="scanning-deployments-using-jandex"><a class="anchor" href="#scanning-deployments-using-jandex"></a>2.16.4. Scanning Deployments Using Jandex</h4>
<div class="paragraph">
<p>If your extension defines annotations or interfaces that mark beans needing to be processed, you can locate these beans using the Jandex API, a Java annotation indexer and offline reflection library. The following <code>TestProcessor#scanForBeans</code> method shows how to find the beans annotated with our <code>@TestAnnotation</code> that also implement the <code>IConfigConsumer</code> interface:</p>
</div>
<div class="listingblock">
<div class="title">Example Jandex Usage</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">    static DotName TEST_ANNOTATION = DotName.createSimple(TestAnnotation.class.getName());
...

    @BuildStep
    @Record(STATIC_INIT)
    void scanForBeans(TestRecorder recorder, BeanArchiveIndexBuildItem beanArchiveIndex, <i class="conum" data-value="1"></i><b>(1)</b>
            BuildProducer&lt;TestBeanBuildItem&gt; testBeanProducer) {
        IndexView indexView = beanArchiveIndex.getIndex(); <i class="conum" data-value="2"></i><b>(2)</b>
        Collection&lt;AnnotationInstance&gt; testBeans = indexView.getAnnotations(TEST_ANNOTATION); <i class="conum" data-value="3"></i><b>(3)</b>
        for (AnnotationInstance ann : testBeans) {
            ClassInfo beanClassInfo = ann.target().asClass();
            try {
                boolean isConfigConsumer = beanClassInfo.interfaceNames()
                        .stream()
                        .anyMatch(dotName -&gt; dotName.equals(DotName.createSimple(IConfigConsumer.class.getName()))); <i class="conum" data-value="4"></i><b>(4)</b>
                if (isConfigConsumer) {
                    Class&lt;IConfigConsumer&gt; beanClass = (Class&lt;IConfigConsumer&gt;) Class.forName(beanClassInfo.name().toString());
                    testBeanProducer.produce(new TestBeanBuildItem(beanClass)); <i class="conum" data-value="5"></i><b>(5)</b>
                    log.infof("Configured bean: %s", beanClass);
                }
            } catch (ClassNotFoundException e) {
                log.warn("Failed to load bean class", e);
            }
        }
    }</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Depend on a <code>BeanArchiveIndexBuildItem</code> to have the build step be run after the deployment has been indexed.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Retrieve the index.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Find all beans annotated with <code>@TestAnnotation</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Determine which of these beans also has the <code>IConfigConsumer</code> interface.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>Save the bean class in a <code>TestBeanBuildItem</code> for use in a latter RUNTIME_INIT build step that will interact with the bean instances.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="interacting-with-extension-beans"><a class="anchor" href="#interacting-with-extension-beans"></a>2.16.5. Interacting With Extension Beans</h4>
<div class="paragraph">
<p>You can use the <code>io.quarkus.arc.runtime.BeanContainer</code> interface to interact with your extension beans. The following <code>configureBeans</code> methods illustrate interacting with the beans scanned for in the previous section:</p>
</div>
<div class="listingblock">
<div class="title">Using CDI BeanContainer Interface</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// TestProcessor#configureBeans
    @BuildStep
    @Record(RUNTIME_INIT)
    void configureBeans(TestRecorder recorder, List&lt;TestBeanBuildItem&gt; testBeans, <i class="conum" data-value="1"></i><b>(1)</b>
            BeanContainerBuildItem beanContainer, <i class="conum" data-value="2"></i><b>(2)</b>
            TestRunTimeConfig runTimeConfig) {

        for (TestBeanBuildItem testBeanBuildItem : testBeans) {
            Class&lt;IConfigConsumer&gt; beanClass = testBeanBuildItem.getConfigConsumer();
            recorder.configureBeans(beanContainer.getValue(), beanClass, buildAndRunTimeConfig, runTimeConfig); <i class="conum" data-value="3"></i><b>(3)</b>
        }
    }

// TestRecorder#configureBeans
    public void configureBeans(BeanContainer beanContainer, Class&lt;IConfigConsumer&gt; beanClass,
            TestBuildAndRunTimeConfig buildTimeConfig,
            TestRunTimeConfig runTimeConfig) {
        log.info("Begin BeanContainerListener callback\n");
        IConfigConsumer instance = beanContainer.instance(beanClass); <i class="conum" data-value="4"></i><b>(4)</b>
        instance.loadConfig(buildTimeConfig, runTimeConfig); <i class="conum" data-value="5"></i><b>(5)</b>
        log.infof("configureBeans, instance=%s\n", instance);
    }</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Consume the `TestBeanBuildItem`s produced from the scanning build step.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Consume the <code>BeanContainerBuildItem</code> to order this build step to run after the CDI bean container has been created.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Call the runtime recorder to record the bean interactions.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Runtime recorder retrieves the bean using its type.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>Runtime recorder invokes the <code>IConfigConsumer#loadConfig(&#8230;&#8203;)</code> method passing in the configuration objects with runtime information.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="manage-non-cdi-service"><a class="anchor" href="#manage-non-cdi-service"></a>2.16.6. Manage Non-CDI Service</h4>
<div class="paragraph">
<p>A common purpose for an extension is to integrate a non-CDI aware service into the CDI based Quarkus runtime. Step 1 of this task is to load any configuration needed in a STATIC_INIT build step as we did in <a href="#parsing-config-to-objects">Parsing Config to Objects</a>. Now we need to create an instance of the service using the configuration. Let&#8217;s return to the <code>TestProcessor#parseServiceXmlConfig</code> method to see how this can be done.</p>
</div>
<div class="listingblock">
<div class="title">Creating a Non-CDI Service</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// TestProcessor#parseServiceXmlConfig
    @BuildStep
    @Record(STATIC_INIT)
    RuntimeServiceBuildItem parseServiceXmlConfig(TestRecorder recorder) throws JAXBException {
        RuntimeServiceBuildItem serviceBuildItem = null;
        JAXBContext context = JAXBContext.newInstance(XmlConfig.class);
        Unmarshaller unmarshaller = context.createUnmarshaller();
        InputStream is = getClass().getResourceAsStream("/config.xml");
        if (is != null) {
            log.info("Have XmlConfig, loading");
            XmlConfig config = (XmlConfig) unmarshaller.unmarshal(is);
            log.info("Loaded XmlConfig, creating service");
            RuntimeValue&lt;RuntimeXmlConfigService&gt; service = recorder.initRuntimeService(config); <i class="conum" data-value="1"></i><b>(1)</b>
            serviceBuildItem = new RuntimeServiceBuildItem(service); <i class="conum" data-value="3"></i><b>(3)</b>
        }
        return serviceBuildItem;
    }

// TestRecorder#initRuntimeService
    public RuntimeValue&lt;RuntimeXmlConfigService&gt; initRuntimeService(XmlConfig config) {
        RuntimeXmlConfigService service = new RuntimeXmlConfigService(config); <i class="conum" data-value="2"></i><b>(2)</b>
        return new RuntimeValue&lt;&gt;(service);
    }

// RuntimeServiceBuildItem
    final public class RuntimeServiceBuildItem extends SimpleBuildItem {
    private RuntimeValue&lt;RuntimeXmlConfigService&gt; service;

    public RuntimeServiceBuildItem(RuntimeValue&lt;RuntimeXmlConfigService&gt; service) {
        this.service = service;
    }

    public RuntimeValue&lt;RuntimeXmlConfigService&gt; getService() {
        return service;
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Call into the runtime recorder to record the creation of the service.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Using the parsed <code>XmlConfig</code> instance, create an instance of <code>RuntimeXmlConfigService</code> and wrap it in a <code>RuntimeValue</code>. Use a <code>RuntimeValue</code> wrapper for non-interface objects that are non-proxiable.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Wrap the return service value in a <code>RuntimeServiceBuildItem</code> for use in a RUNTIME_INIT build step that will start the service.</td>
</tr>
</table>
</div>
<div class="sect4">
<h5 id="starting-a-service"><a class="anchor" href="#starting-a-service"></a>2.16.6.1. Starting a Service</h5>
<div class="paragraph">
<p>Now that you have recorded the creation of a service during the build phase, you need to record how to start the service at runtime during booting. You do this with a RUNTIME_INIT build step as shown in the <code>TestProcessor#startRuntimeService</code> method.</p>
</div>
<div class="listingblock">
<div class="title">Starting/Stopping a Non-CDI Service</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// TestProcessor#startRuntimeService
    @BuildStep
    @Record(RUNTIME_INIT)
    ServiceStartBuildItem startRuntimeService(TestRecorder recorder, ShutdownContextBuildItem shutdownContextBuildItem , <i class="conum" data-value="1"></i><b>(1)</b>
            RuntimeServiceBuildItem serviceBuildItem) throws IOException { <i class="conum" data-value="2"></i><b>(2)</b>
        if (serviceBuildItem != null) {
            log.info("Registering service start");
            recorder.startRuntimeService(shutdownContextBuildItem, serviceBuildItem.getService()); <i class="conum" data-value="3"></i><b>(3)</b>
        } else {
            log.info("No RuntimeServiceBuildItem seen, check config.xml");
        }
        return new ServiceStartBuildItem("RuntimeXmlConfigService"); <i class="conum" data-value="4"></i><b>(4)</b>
    }

// TestRecorder#startRuntimeService
    public void startRuntimeService(ShutdownContext shutdownContext, RuntimeValue&lt;RuntimeXmlConfigService&gt; runtimeValue)
            throws IOException {
        RuntimeXmlConfigService service = runtimeValue.getValue();
        service.startService(); <i class="conum" data-value="5"></i><b>(5)</b>
        shutdownContext.addShutdownTask(service::stopService); <i class="conum" data-value="6"></i><b>(6)</b>
    }</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>We consume a ShutdownContextBuildItem to register the service shutdown.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>We consume the previously initialized service captured in <code>RuntimeServiceBuildItem</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Call the runtime recorder to record the service start invocation.</td>
</tr>
<tr>
<td><i class="conum" data-value="4"></i><b>4</b></td>
<td>Produce a <code>ServiceStartBuildItem</code> to indicate the startup of a service. See <a href="#startup-and-shutdown-events">Startup and Shutdown Events</a> for details.</td>
</tr>
<tr>
<td><i class="conum" data-value="5"></i><b>5</b></td>
<td>Runtime recorder retrieves the service instance reference and calls its <code>startService</code> method.</td>
</tr>
<tr>
<td><i class="conum" data-value="6"></i><b>6</b></td>
<td>Runtime recorder registers an invocation of the service instance <code>stopService</code> method with the Quarkus <code>ShutdownContext</code>.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>The code for the <code>RuntimeXmlConfigService</code> can be viewed here:
{quarkus-blob-url}/core/test-extension/runtime/src/main/java/io/quarkus/extest/runtime/RuntimeXmlConfigService.java[RuntimeXmlConfigService.java]</p>
</div>
<div class="paragraph">
<p>The testcase for validating that the <code>RuntimeXmlConfigService</code> has started can be found in the <code>testRuntimeXmlConfigService</code> test of <code>ConfiguredBeanTest</code> and <code>NativeImageIT</code>.</p>
</div>
</div>
</div>
<div class="sect3">
<h4 id="startup-and-shutdown-events"><a class="anchor" href="#startup-and-shutdown-events"></a>2.16.7. Startup and Shutdown Events</h4>
<div class="paragraph">
<p>The Quarkus container supports startup and shutdown lifecycle events to notify components of the container startup
and shutdown. There are CDI events fired that components can observe are illustrated in this example:</p>
</div>
<div class="listingblock">
<div class="title">Observing Container Startup</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">import io.quarkus.runtime.ShutdownEvent;
import io.quarkus.runtime.StartupEvent;

puclic class SomeBean {
    /**
     * Called when the runtime has started
     * @param event
     */
    void onStart(@Observes StartupEvent event) { <i class="conum" data-value="1"></i><b>(1)</b>
        System.out.printf("onStart, event=%s%n", event);
    }

    /**
     * Called when the runtime is shutting down
     * @param event
    */
    void onStop(@Observes ShutdownEvent event) { <i class="conum" data-value="2"></i><b>(2)</b>
        System.out.printf("onStop, event=%s%n", event);
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Observe a <code>StartupEvent</code> to be notified the runtime has started.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Observe a 'ShutdownEvent` to be notified when the runtime is going to shutdown.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>What is the relevance of startup and shutdown events for extension authors? We have already seen the use of a <code>ShutdownContext</code>
to register a callback to perform shutdown tasks in the <a href="#starting-a-service">Starting a Service</a> section. These shutdown tasks would be called
after a <code>ShutdownEvent</code> had been sent.</p>
</div>
<div class="paragraph">
<p>A <code>StartupEvent</code> is fired after all <code>io.quarkus.deployment.builditem.ServiceStartBuildItem</code> producers have been consumed.
The implication of this is that if an extension has services that application components would expect to have been
started when they observe a <code>StartupEvent</code>, the build steps that invoke the runtime code to start those services needs
to produce a <code>ServiceStartBuildItem</code> to ensure that the runtime code is run before the <code>StartupEvent</code> is sent. Recall that
we saw the production of a <code>ServiceStartBuildItem</code> in the previous section, and it is repeated here for clarity:</p>
</div>
<div class="listingblock">
<div class="title">Example of Producing a ServiceStartBuildItem</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// TestProcessor#startRuntimeService
    @BuildStep
    @Record(RUNTIME_INIT)
    ServiceStartBuildItem startRuntimeService(TestRecorder recorder, ShutdownContextBuildItem shutdownContextBuildItem,
            RuntimeServiceBuildItem serviceBuildItem) throws IOException {
...
        return new ServiceStartBuildItem("RuntimeXmlConfigService"); <i class="conum" data-value="1"></i><b>(1)</b>
    }</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Produce a <code>ServiceStartBuildItem</code> to indicate that this is a service starting step that needs to run before the <code>StartupEvent</code> is sent.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="register-resources-for-use-in-native-image"><a class="anchor" href="#register-resources-for-use-in-native-image"></a>2.16.8. Register Resources for Use in Native Image</h4>
<div class="paragraph">
<p>Not all configuration or resources can be consumed at build time. If you have classpath resources that the runtime needs to access, you need to inform the build phase that these resources need to be copied into the native image. This is done by producing one or more <code>NativeImageResourceBuildItem</code> or <code>NativeImageResourceBundleBuildItem</code> in the case of resource bundles. Examples of this are shown in this sample <code>registerNativeImageResources</code> build step:</p>
</div>
<div class="listingblock">
<div class="title">Registering Resources and ResourceBundles</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public final class MyExtProcessor {
    @Inject
    BuildProducer&lt;NativeImageResourceBuildItem&gt; resource;
    @Inject
    BuildProducer&lt;NativeImageResourceBundleBuildItem&gt; resourceBundle;

    @BuildStep
    void registerNativeImageResources() {
        resource.produce(new NativeImageResourceBuildItem("/security/runtime.keys")); <i class="conum" data-value="1"></i><b>(1)</b>

        resource.produce(new NativeImageResourceBuildItem(
                "META-INF/my-descriptor.xml")); <i class="conum" data-value="2"></i><b>(2)</b>

        resourceBundle.produce(new NativeImageResourceBuildItem("javax.xml.bind.Messages")); <i class="conum" data-value="3"></i><b>(3)</b>
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>Indicate that the /security/runtime.keys classpath resource should be copied into native image.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>Indicate that the <code>META-INF/my-descriptor.xml</code> resource should be copied into native image</td>
</tr>
<tr>
<td><i class="conum" data-value="3"></i><b>3</b></td>
<td>Indicate that the "javax.xml.bind.Messages" resource bundle should be copied into native image.</td>
</tr>
</table>
</div>
</div>
<div class="sect3">
<h4 id="service-files"><a class="anchor" href="#service-files"></a>2.16.9. Service files</h4>
<div class="paragraph">
<p>If you are using <code>META-INF/services</code> files you need to register the files as resources so that your native image can find them,
but you also need to register each listed class for reflection so they can be instantiated or inspected at run-time:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public final class MyExtProcessor {

    @BuildStep
    void registerNativeImageResources(BuildProducer&lt;ServiceProviderBuildItem&gt; services) {
        String service = "META-INF/services/" + io.quarkus.SomeService.class.getName();

        // find out all the implementation classes listed in the service files
        Set&lt;String&gt; implementations =
            ServiceUtil.classNamesNamedIn(Thread.currentThread().getContextClassLoader(),
                                          service);

        // register every listed implementation class so they can be instantiated
        // in native-image at run-time
        services.produce(
            new ServiceProviderBuildItem(io.quarkus.SomeService.class.getName(),
                                         implementations.toArray(new String[0])));
    }
}</code></pre>
</div>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<code>ServiceProviderBuildItem</code> takes a list of service implementation classes as parameters: if
you are not reading them from the service file, make sure that they correspond to the service file contents
because the service file will still be read and used at run-time. This is not a substitute for writing a service
file.
</td>
</tr>
</table>
</div>
<div class="admonitionblock note">
<table>
<tr>
<td class="icon">
<i class="fa icon-note" title="Note"></i>
</td>
<td class="content">
This only registers the implementation classes for instantiation via reflection (you will not be able
to inspect its fields and methods). If you need to do that, you can do it this way:
</td>
</tr>
</table>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public final class MyExtProcessor {

    @BuildStep
    void registerNativeImageResources(BuildProducer&lt;NativeImageResourceBuildItem&gt; resource,
                                     BuildProducer&lt;ReflectiveClassBuildItem&gt; reflectionClasses) {
        String service = "META-INF/services/" + io.quarkus.SomeService.class.getName();

        // register the service file so it is visible in native-image
        resource.produce(new NativeImageResourceBuildItem(service));

        // register every listed implementation class so they can be inspected/instantiated
        // in native-image at run-time
        Set&lt;String&gt; implementations =
            ServiceUtil.classNamesNamedIn(Thread.currentThread().getContextClassLoader(),
                                          service);
        reflectionClasses.produce(
            new ReflectiveClassBuildItem(true, true, implementations.toArray(new String[0])));
    }
}</code></pre>
</div>
</div>
<div class="paragraph">
<p>While this is the easiest way to get your services running natively, it&#8217;s less efficient than scanning the implementation
classes at build time and generating code that registers them at static-init time instead of relying on reflection.</p>
</div>
<div class="paragraph">
<p>You can achieve that by adapting the previous build step to use a static-init recorder instead of registering
classes for reflection:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">public final class MyExtProcessor {

    @BuildStep
    @Record(ExecutionTime.STATIC_INIT)
    void registerNativeImageResources(RecorderContext recorderContext,
                                     SomeServiceRecorder recorder) {
        String service = "META-INF/services/" + io.quarkus.SomeService.class.getName();

        // read the implementation classes
        Collection&lt;Class&lt;? extends io.quarkus.SomeService&gt;&gt; implementationClasses = new LinkedHashSet&lt;&gt;();
        Set&lt;String&gt; implementations = ServiceUtil.classNamesNamedIn(Thread.currentThread().getContextClassLoader(),
                                                                    service);
        for(String implementation : implementations) {
            implementationClasses.add((Class&lt;? extends io.quarkus.SomeService&gt;)
                recorderContext.classProxy(implementation));
        }

        // produce a static-initializer with those classes
        recorder.configure(implementationClasses);
    }
}

@Recorder
public class SomeServiceRecorder {

    public void configure(List&lt;Class&lt;? extends io.quarkus.SomeService&gt;&gt; implementations) {
        // configure our service statically
        SomeServiceProvider serviceProvider = SomeServiceProvider.instance();
        SomeServiceBuilder builder = serviceProvider.getSomeServiceBuilder();

        List&lt;io.quarkus.SomeService&gt; services = new ArrayList&lt;&gt;(implementations.size());
        // instantiate the service implementations
        for (Class&lt;? extends io.quarkus.SomeService&gt; implementationClass : implementations) {
            try {
                services.add(implementationClass.getConstructor().newInstance());
            } catch (Exception e) {
                throw new IllegalArgumentException("Unable to instantiate service " + implementationClass, e);
            }
        }

        // build our service
        builder.withSomeServices(implementations.toArray(new io.quarkus.SomeService[0]));
        ServiceManager serviceManager = builder.build();

        // register it
        serviceProvider.registerServiceManager(serviceManager, Thread.currentThread().getContextClassLoader());
    }
}</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="object-substitution"><a class="anchor" href="#object-substitution"></a>2.16.10. Object Substitution</h4>
<div class="paragraph">
<p>Objects created during the build phase that are passed into the runtime need to have a default constructor in order for them to be created and configured at startup of the runtime from the build time state. If an object does not have a default constructor you will see an error similar to the following during generation of the augmented artifacts:</p>
</div>
<div class="listingblock">
<div class="title">DSAPublicKey Serialization Error</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="bash" class="language-bash hljs">	[error]: Build step io.quarkus.deployment.steps.MainClassBuildStep#build threw an exception: java.lang.RuntimeException: Unable to serialize objects of type class sun.security.provider.DSAPublicKeyImpl to bytecode as it has no default constructor
	at io.quarkus.builder.Execution.run(Execution.java:123)
	at io.quarkus.builder.BuildExecutionBuilder.execute(BuildExecutionBuilder.java:136)
	at io.quarkus.deployment.QuarkusAugmentor.run(QuarkusAugmentor.java:110)
	at io.quarkus.runner.RuntimeRunner.run(RuntimeRunner.java:99)
	... 36 more</code></pre>
</div>
</div>
<div class="paragraph">
<p>There is a <code>io.quarkus.runtime.ObjectSubstitution</code> interface that can be implemented to tell Quarkus how to handle such classes. An example implementation for the <code>DSAPublicKey</code> is shown here:</p>
</div>
<div class="listingblock">
<div class="title">DSAPublicKeyObjectSubstitution Example</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package io.quarkus.extest.runtime.subst;

import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.logging.Logger;

import io.quarkus.runtime.ObjectSubstitution;

public class DSAPublicKeyObjectSubstitution implements ObjectSubstitution&lt;DSAPublicKey, KeyProxy&gt; {
    private static final Logger log = Logger.getLogger("DSAPublicKeyObjectSubstitution");
    @Override
    public KeyProxy serialize(DSAPublicKey obj) { <i class="conum" data-value="1"></i><b>(1)</b>
        log.info("DSAPublicKeyObjectSubstitution.serialize");
        byte[] encoded = obj.getEncoded();
        KeyProxy proxy = new KeyProxy();
        proxy.setContent(encoded);
        return proxy;
    }

    @Override
    public DSAPublicKey deserialize(KeyProxy obj) { <i class="conum" data-value="2"></i><b>(2)</b>
        log.info("DSAPublicKeyObjectSubstitution.deserialize");
        byte[] encoded = obj.getContent();
        X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encoded);
        DSAPublicKey dsaPublicKey = null;
        try {
            KeyFactory kf = KeyFactory.getInstance("DSA");
            dsaPublicKey = (DSAPublicKey) kf.generatePublic(publicKeySpec);

        } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return dsaPublicKey;
    }
}</code></pre>
</div>
</div>
<div class="colist arabic">
<table>
<tr>
<td><i class="conum" data-value="1"></i><b>1</b></td>
<td>The serialize method takes the object without a default constructor and creates a <code>KeyProxy</code> that contains the information necessary to recreate the <code>DSAPublicKey</code>.</td>
</tr>
<tr>
<td><i class="conum" data-value="2"></i><b>2</b></td>
<td>The deserialize method uses the <code>KeyProxy</code> to recreate the <code>DSAPublicKey</code> from its encoded form using the key factory.</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>An extension registers this substitution by producing an <code>ObjectSubstitutionBuildItem</code> as shown in this <code>TestProcessor#loadDSAPublicKey</code> fragment:</p>
</div>
<div class="listingblock">
<div class="title">Registering an Object Subtitution</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">    @BuildStep
    @Record(STATIC_INIT)
    PublicKeyBuildItem loadDSAPublicKey(TestRecorder recorder,
            BuildProducer&lt;ObjectSubstitutionBuildItem&gt; substitutions) throws IOException, GeneralSecurityException {
...
        // Register how to serialize DSAPublicKey
        ObjectSubstitutionBuildItem.Holder&lt;DSAPublicKey, KeyProxy&gt; holder = new ObjectSubstitutionBuildItem.Holder(
                DSAPublicKey.class, KeyProxy.class, DSAPublicKeyObjectSubstitution.class);
        ObjectSubstitutionBuildItem keysub = new ObjectSubstitutionBuildItem(holder);
        substitutions.produce(keysub);

        log.info("loadDSAPublicKey run");
        return new PublicKeyBuildItem(publicKey);
    }</code></pre>
</div>
</div>
</div>
<div class="sect3">
<h4 id="replacing-classes-in-the-native-image"><a class="anchor" href="#replacing-classes-in-the-native-image"></a>2.16.11. Replacing Classes in the Native Image</h4>
<div class="paragraph">
<p>The Graal SDK supports substitutions of classes in the native image. An example of how one could replace the <code>XmlConfig/XmlData</code> classes with versions that have no JAXB annotation dependencies is shown in these example classes:</p>
</div>
<div class="listingblock">
<div class="title">Substitution of XmlConfig/XmlData Classes Example</div>
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">package io.quarkus.extest.runtime.graal;
import java.util.Date;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import io.quarkus.extest.runtime.config.XmlData;

@TargetClass(XmlConfig.class)
@Substitute
public final class Target_XmlConfig {

    @Substitute
    private String address;
    @Substitute
    private int port;
    @Substitute
    private ArrayList&lt;XData&gt; dataList;

    @Substitute
    public String getAddress() {
        return address;
    }

    @Substitute
    public int getPort() {
        return port;
    }

    @Substitute
    public ArrayList&lt;XData&gt; getDataList() {
        return dataList;
    }

    @Substitute
    @Override
    public String toString() {
        return "Target_XmlConfig{" +
                "address='" + address + '\'' +
                ", port=" + port +
                ", dataList=" + dataList +
                '}';
    }
}

@TargetClass(XmlData.class)
@Substitute
public final class Target_XmlData {

    @Substitute
    private String name;
    @Substitute
    private String model;
    @Substitute
    private Date date;

    @Substitute
    public String getName() {
        return name;
    }

    @Substitute
    public String getModel() {
        return model;
    }

    @Substitute
    public Date getDate() {
        return date;
    }

    @Substitute
    @Override
    public String toString() {
        return "Target_XmlData{" +
                "name='" + name + '\'' +
                ", model='" + model + '\'' +
                ", date='" + date + '\'' +
                '}';
    }
}</code></pre>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="configuration-reference-documentation"><a class="anchor" href="#configuration-reference-documentation"></a>3. Configuration reference documentation</h2>
<div class="sectionbody">
<div class="paragraph">
<p>The configuration is an important part of each extension and therefore needs to be properly documented.
Each configuration property should have a proper Javadoc comment.</p>
</div>
<div class="paragraph">
<p>While it is handy to have the documentation available when coding, this configuration documentation must also be available in the extension guides.
The Quarkus build automatically generates the configuration documentation for you based on the Javadoc comments but you need to explicitly include it in your guide.</p>
</div>
<div class="paragraph">
<p>In this section, we will explain everything you need to know about the configuration reference documentation.</p>
</div>
<div class="sect2">
<h3 id="writing-the-documentation"><a class="anchor" href="#writing-the-documentation"></a>3.1. Writing the documentation</h3>
<div class="paragraph">
<p>For each configuration property, you need to write some Javadoc explaining its purpose.</p>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>Always make the first sentence meaningful and self-contained as it is included in the summary table.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
<p>You can either use standard Javadoc comments or Asciidoc directly as a Javadoc comment.</p>
</div>
<div class="paragraph">
<p>We assume you are familiar with writing Javadoc comments so let&#8217;s focus on our Asciidoc support.
While standard Javadoc comments are perfectly fine for simple documentation (recommended even),
if you want to include tips, source code extracts, lists&#8230;&#8203; Asciidoc comes in handy.</p>
</div>
<div class="paragraph">
<p>Here is a typical configuration property commented with Asciidoc:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">/**
 * Class name of the Hibernate ORM dialect. The complete list of bundled dialects is available in the
 * https://docs.jboss.org/hibernate/stable/orm/javadocs/org/hibernate/dialect/package-summary.html[Hibernate ORM JavaDoc].
 *
 * [NOTE]
 * ====
 * Not all the dialects are supported in GraalVM native executables: we currently provide driver extensions for PostgreSQL,
 * MariaDB, Microsoft SQL Server and H2.
 * ====
 *
 * @asciidoclet
 */
@ConfigItem
public Optional&lt;String&gt; dialect;</code></pre>
</div>
</div>
<div class="paragraph">
<p>This is the simple case: you just have to write Asciidoc and mark the comment with the <code>@asciidoclet</code> tag.
This tag has two purposes: it is used as a marker for our generation tool but it is also used by the <code>javadoc</code> process for proper Javadoc generation.</p>
</div>
<div class="paragraph">
<p>Now let&#8217;s consider a more complicated example:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">// @formatter:off
/**
 * Name of the file containing the SQL statements to execute when Hibernate ORM starts.
 * Its default value differs depending on the Quarkus launch mode:
 *
 * * In dev and test modes, it defaults to `import.sql`.
 *   Simply add an `import.sql` file in the root of your resources directory
 *   and it will be picked up without having to set this property.
 *   Pass `no-file` to force Hibernate ORM to ignore the SQL import file.
 * * In production mode, it defaults to `no-file`.
 *   It means Hibernate ORM won't try to execute any SQL import file by default.
 *   Pass an explicit value to force Hibernate ORM to execute the SQL import file.
 *
 * If you need different SQL statements between dev mode, test (`@QuarkusTest`) and in production, use Quarkus
 * https://quarkus.io/guides/config#configuration-profiles[configuration profiles facility].
 *
 * [source,property]
 * .application.properties
 * ----
 * %dev.quarkus.hibernate-orm.sql-load-script = import-dev.sql
 * %test.quarkus.hibernate-orm.sql-load-script = import-test.sql
 * %prod.quarkus.hibernate-orm.sql-load-script = no-file
 * ----
 *
 * [NOTE]
 * ====
 * Quarkus supports `.sql` file with SQL statements or comments spread over multiple lines.
 * Each SQL statement must be terminated by a semicolon.
 * ====
 *
 * @asciidoclet
 */
// @formatter:on
@ConfigItem
public Optional&lt;String&gt; sqlLoadScript;</code></pre>
</div>
</div>
<div class="paragraph">
<p>A few comments on this one:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Every time you will need the indentation to be respected in the Javadoc comment (think list items spread on multiple lines or indented source code),
you will need to disable temporarily the automatic Eclipse formatter
(this, even if you don&#8217;t use Eclipse as the formatter is included in our build).
To do so, use the <code>// @formatter:off</code>/<code>// @formatter:on</code> markers.
Note the fact that they are separate comments and there is a space after the <code>//</code> marker. This is required.</p>
</li>
<li>
<p>As you can see, you can use the full power of Asciidoctor (except for the limitation below)</p>
</li>
</ul>
</div>
<div class="admonitionblock warning">
<table>
<tr>
<td class="icon">
<i class="fa icon-warning" title="Warning"></i>
</td>
<td class="content">
<div class="paragraph">
<p>You cannot use open blocks (<code>--</code>) in your Asciidoctor documentation.
All the other types of blocks (source, admonitions&#8230;&#8203;) are supported.</p>
</div>
</td>
</tr>
</table>
</div>
<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
<div class="paragraph">
<p>By default, the doc generator will use the hyphenated field name as the key of a <code>java.util.Map</code> configuration item.
To override this default and have a user friendly key (independent of implementation details), you may use the <code>io.quarkus.runtime.annotations.ConfigDocMapKey</code> annotation.
See the following example,</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">@ConfigRoot
public class SomeConfig {
    /**
     * Namespace configuration.
     */
    @ConfigItem(name = ConfigItem.PARENT)
    @ConfigDocMapKey("cache-name") <i class="conum" data-value="1"></i><b>(1)</b>
    Map&lt;String, CaffeineNamespaceConfig&gt; namespace;
}</code></pre>
</div>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>This will generate a configuration map key named <code>quarkus.some."cache-name"</code> instead of <code>quarkus.some."namespace"</code>.</p>
</li>
</ol>
</div>
</td>
</tr>
</table>
</div>
</div>
<div class="sect2">
<h3 id="writing-section-documentation"><a class="anchor" href="#writing-section-documentation"></a>3.2. Writing section documentation</h3>
<div class="paragraph">
<p>If you wish to generate configuration section of a given <code>@ConfigGroup</code>, Quarkus has got you covered with the <code>@ConfigDocSection</code> annotation.
See the code  example below:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="java" class="language-java hljs">/**
* Config group related configuration.
* Amazing introduction here
*/
@ConfigItem
@ConfigDocSection <i class="conum" data-value="1"></i><b>(1)</b>
public ConfigGroupConfig configGroup;</code></pre>
</div>
</div>
<div class="olist arabic">
<ol class="arabic">
<li>
<p>This will add a section documentation for the <code>configGroup</code> config item in the generated documentation.
Section&#8217;s title and introduction will be derived from the javadoc of the configuration item. The first sentence from the javadoc is considered as the section title and the remaining sentences used as section introduction.
You can also use the <code>@asciidoclet</code> tag as shown above.</p>
</li>
</ol>
</div>
</div>
<div class="sect2">
<h3 id="generating-the-documentation"><a class="anchor" href="#generating-the-documentation"></a>3.3. Generating the documentation</h3>
<div class="paragraph">
<p>Generating the documentation is easy:</p>
</div>
<div class="ulist">
<ul>
<li>
<p>Running <code>./mvnw clean install -DskipTests -DskipITs</code> will do.</p>
</li>
<li>
<p>You  can either do it globally or in a specific extension directory (e.g. <code>extensions/mailer</code>).</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>The documentation is generated in the global <code>target/asciidoc/generated/config/</code> located at the root of the project.</p>
</div>
</div>
<div class="sect2">
<h3 id="including-the-documentation-in-the-extension-guide"><a class="anchor" href="#including-the-documentation-in-the-extension-guide"></a>3.4. Including the documentation in the extension guide</h3>
<div class="paragraph">
<p>Now that you have generated the configuration reference documentation for your extension, you need to include it in your guide (and review it).</p>
</div>
<div class="paragraph">
<p>This is simple, include the generated documentation in your guide:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="asciidoc" class="language-asciidoc hljs">include::{generated-dir}/config/quarkus-your-extension.adoc[opts=optional, leveloffset=+1]</code></pre>
</div>
</div>
<div class="paragraph">
<p>If you are interested in including the generated documentation for the config group, you can use the include statement below</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="asciidoc" class="language-asciidoc hljs">include::{generated-dir}/config/hyphenated-config-group-class-name-with-runtime-or-deployment-namespace-replaced-by-config-group-namespace.adoc[opts=optional, leveloffset=+1]</code></pre>
</div>
</div>
<div class="paragraph">
<p>For example, the <code>io.quarkus.vertx.http.runtime.FormAuthConfig</code> configuration group will be generated in a file named <code>quarkus-vertx-http-config-group-form-auth-config.adoc</code>.</p>
</div>
<div class="paragraph">
<p>A few recommendations:</p>
</div>
<div class="ulist">
<ul>
<li>
<p><code>opts=optional</code> is mandatory as we don&#8217;t want the build to fail if only part of the configuration documentation has been generated</p>
</li>
<li>
<p>The documentation is generated with a title level of 2 (i.e. <code>==</code>).
You usually need to adjust it.
It can be done with <code>leveloffset=+N</code>.</p>
</li>
</ul>
</div>
<div class="paragraph">
<p>It is not recommended to include the whole configuration documentation in the middle of your guide as it&#8217;s heavy.
If you have an <code>application.properties</code> extract with your configuration, just do as follows.</p>
</div>
<div class="paragraph">
<p>First, include a tip just below your <code>application.properties</code> extract:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="asciidoc" class="language-asciidoc hljs">[TIP]
For more information about the extension configuration please refer to the &lt;&lt;configuration-reference, Configuration Reference&gt;&gt;.</code></pre>
</div>
</div>
<div class="paragraph">
<p>Then, at the end of your documentation, include the extensive documentation:</p>
</div>
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code data-lang="asciidoc" class="language-asciidoc hljs">[[configuration-reference]]
== Configuration Reference

include::{generated-dir}/config/quarkus-your-extension.adoc[opts=optional, leveloffset=+1]</code></pre>
</div>
</div>
<div class="paragraph">
<p>Finally, generate the documentation and check it out.</p>
</div>
</div>
</div>
</div>
<div class="sect1">
<h2 id="continuous-testing-of-your-extension"><a class="anchor" href="#continuous-testing-of-your-extension"></a>4. Continuous testing of your extension</h2>
<div class="sectionbody">
<div class="paragraph">
<p>In order to make it easy for extension authors to test their extensions daily against the latest snapshot of Quarkus, Quarkus has introduced
the notion of Ecosystem CI. The Ecosystem CI <a href="https://github.com/quarkusio/quarkus-ecosystem-ci/blob/master/README.adoc">README</a>
has all the details on how to set up a GitHub Actions job to take advantage of this capability, while this <a href="https://www.youtube.com/watch?v=VpbRA1n0hHQ">video</a> provides an overview
of what the process looks like.</p>
</div>
</div>
</div>
    </div>
  </div>
</div>

  </div>

  <div class="content project-footer">
  <div class="footer-section">
    <div class="logo-wrapper">
      <a href="/"><img src="/assets/images/quarkus_logo_horizontal_rgb_reverse.svg" class="project-logo" title="Quarkus"></a>
    </div>
  </div>
  <div class="grid-wrapper">
    <p class="grid__item width-3-12">Quarkus is open. All dependencies of this project are available under the <a href='https://www.apache.org/licenses/LICENSE-2.0' target='_blank'>Apache Software License 2.0</a> or compatible license.<br /><br />This website was built with <a href='https://jekyllrb.com/' target='_blank'>Jekyll</a>, is hosted on <a href='https://pages.github.com/' target='_blank'>Github Pages</a> and is completely open source. If you want to make it better, <a href='https://github.com/quarkusio/quarkusio.github.io' target='_blank'>fork the website</a> and show us what you’ve got.</p>

    
      <div class="width-1-12 project-links">
        <span>Navigation</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="/">Home</a></li>
          
            <li><a href="/guides">Guides</a></li>
          
            <li><a href="/community/#contributing">Contribute</a></li>
          
            <li><a href="/faq">FAQ</a></li>
          
            <li><a href="/get-started">Get Started</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Contribute</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://twitter.com/quarkusio">Follow us</a></li>
          
            <li><a href="https://github.com/quarkusio">GitHub</a></li>
          
            <li><a href="/security">Security&nbsp;policy</a></li>
          
        </ul>
      </div>
    
      <div class="width-1-12 project-links">
        <span>Get Help</span>
        <ul class="footer-links width-1-12">
          
            <li><a href="https://groups.google.com/forum/#!forum/quarkus-dev">Forums</a></li>
          
            <li><a href="https://quarkusio.zulipchat.com">Chatroom</a></li>
          
        </ul>
      </div>
    

    
      <div class="width-3-12 more-links">
        <span>Quarkus is made of community projects</span>
        <ul class="footer-links">
          
            <li><a href="https://vertx.io/" target="_blank">Eclipse Vert.x</a></li>
          
            <li><a href="https://microprofile.io" target="_blank">Eclipse MicroProfile</a></li>
          
            <li><a href="https://hibernate.org" target="_blank">Hibernate</a></li>
          
            <li><a href="https://netty.io" target="_blank">Netty</a></li>
          
            <li><a href="https://resteasy.github.io" target="_blank">RESTEasy</a></li>
          
            <li><a href="https://camel.apache.org" target="_blank">Apache Camel</a></li>
          
            <li><a href="https://code.quarkus.io/" target="_blank">And many more...</a></li>
          
        </ul>
      </div>
    
  </div>
</div>
  <div class="content redhat-footer">
  <div class="grid-wrapper">
    <span class="licence">
      <i class="fab fa-creative-commons"></i><i class="fab fa-creative-commons-by"></i> <a href="https://creativecommons.org/licenses/by/3.0/" target="_blank">CC by 3.0</a> | <a href="https://www.redhat.com/en/about/privacy-policy">Privacy Policy</a>
    </span>
    <span class="redhat">
      Sponsored by
    </span>
    <span class="redhat-logo">
      <a href="https://www.redhat.com/" target="_blank"><img src="/assets/images/redhat_reversed.svg"></a>
    </span>
  </div>
</div>


  <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js" integrity="sha384-8gBf6Y4YYq7Jx97PIqmTwLPin4hxIzQw5aDmUg/DDhul9fFpbbLcLh3nTIIDJKhx" crossorigin="anonymous"></script>
  <script type="text/javascript" src="/assets/javascript/mobile-nav.js"></script>
  <script type="text/javascript" src="/assets/javascript/scroll-down.js"></script>
  <script src="/assets/javascript/satellite.js" type="text/javascript"></script>
  <script src="https://quarkus.io/guides/javascript/config.js" type="text/javascript"></script>
  <script src="/assets/javascript/search-filter.js" type="text/javascript"></script>
  <script src="/assets/javascript/back-to-top.js" type="text/javascript"></script>
</body>

</html>
